This document is the preregistration for the Preferential Physics project on Lookit. Data collection is currently underway, but sample size has been set prior to data collection kickoff (50 participants reaching 12th session), and the vast majority of videos haven’t even been coded for looks, much less critical DVs calculated.

This document contains a brief orientation to the project, links to relevant other documentation, and a reproducible set of analyses that reads in a set of pilot data, generates a simulated dataset, and attempts to set up the model comparisons we actually care about!

Introduction

The idea is to use dense sampling of individual infants on Lookit to conduct a detailed assessment of understanding of several physical principles. How stable are individual components across sessions and how independent? What does partial knowledge look like at the individual level?

We are interested in infants’ preferential looking ratio to simple violations of:

  • Gravity: Completely unsupported objects should fall down immediately, rather than moving up, continuing in their current trajectory, or moving down at some delay.

  • Inertia: Objects should continue roughly in their current trajectory when gravity is not a factor, rather than stopping and starting or turning around.

  • Support: which of the following should fall (vs. stay put) after being placed?

    • An object placed mostly on the anchor

    • An object placed only slightly on the anchor

    • An object touching the side or bottom of the anchor

    • An object near the anchor but not touching it

Big picture

Why study individual behavior in more detail–what do we lose in studying groups of kids? We don’t know the extent to which a success means that a significant fraction of kids this age can do this task VS that all kids of this age can do this task to a significant degree. And even looking at the distribution of scores doesn’t clear this up, unless it’s an incredibly strong result (e.g. all kids get 9-10 of 10 questions right, or no kids get more than 6 out of 10). This matters for

  • understanding how abilities are related to each other: we can’t get nearly as much out of age-based progressions without knowing how the noise works—especially for results of the form “n-month-olds, but not m-month-olds, can do X”

  • understanding what partial knowledge & mechanisms of change in a domain look like: when kids “fail,” is that some kids making a correct prediction and some making an incorrect prediction? Or are they all failing to make any prediction and/or predicting at chance? When kids succeed but not at ceiling, are some getting one aspect and some another?

It may be that some kids don’t express nearly-universal knowledge on the dependent measures we collect. We can evaluate this explanation for noise and/or individual differences by studying the methods themselves, and kids’ behavior on them: e.g., can we predict the types of preferential looking responses we get from kids based on control tasks? How stable are those controls and task performance across sessions? (Especially interesting would be differences within kids in expression: kids may genuinely express knowledge at some times, but not others, due to attentional/emotional state changes.)

Especially in development, where we’re interested in the underpinnings of human cognition, the difference between “some babies use this type of information but others do something else” and “all babies have this type of information available to them, unless something’s wrong” matters a lot—this is exactly where we care about universality.

Experimental paradigm

Children complete 24 20-second preferential looking trials per session; families are encouraged to complete 15 sessions within 2 months. Parents complete a short mood survey and go through some instructions before the preferential looking portion. They’re asked to hold their children looking over their shoulders during this portion to avoid parental bias. Parents can end the study at any point and skip to the post-study survey.

Each trial begins with an object intro (video of Kim saying “Look, this is a …”) and demonstrating use of an object – e.g. biting into an apple, putting on hand lotion, drawing with a marker, eating with a spoon) that lasts about 5 seconds.

This is intended as an attention-getter to re-orient children towards the center, while in principle reinforcing that the object in question is not an agent and should be expected to follow normal physical laws.

Then, two events involving that object are shown simultaneously, one on the left and one on the right, looping for 24s (event videos range from about 2-5s). Events always show the same object, same camera angle, same background, with a difference only in the “outcome.” Event types are shown in the table below; each concept is presented 4-6 times, with 2-3 repetitions of each event type. Although events are short, they loop continuously for 20s. Realtime events are shown so that “expected” events are at natural speeds, and not potentially seen as violating physical principles due to happening too slowly.

Parents can pause individual trials. If they pause during the intro, they just start over upon restarting. If they pause during the test (up to one time per trial) they restart from the intro, but then the left and right test videos are switched for the test phase.

Trial assignment & ordering

(See below for descriptions of these trial types.) Trials cycle through gravity, inertia+calibration, support, and control (same/salience) pairings during a session; the order of these concepts is chosen from a list and changed (cycling through a list of orders) each session. There are six videos shown in each category in total.

Within each category, objects are assigned to comparison types (e.g. “apple” assigned to “table, down vs. up”) by choosing from a list of acceptable mappings, again incremented per session. (The first session value was selected randomly from the first six options initially [by accident], and is now selected from all possible mappings.)

There are six possible comparisons for the stay and fall events; three comparisons are assigned to stay and three to fall, with the selection again cycling through a random list of such assignments per session. Left/right placement, horizontal flipping of the left and right events, camera angles, and backgrounds are chosen randomly with the constraint that half of the ‘more probable’ events are on the left within each category. Calibration trials (grouped with inertia videos for purposes of assigning object intros) are placed at trials 3 and 6, so that they are always available for kids who completed enough trials for the session to be included (and so that if there are differences in coding quality across trials, we’re not excluding on the basis of when calibration happened).

Event types

Gravity

Table

Object is rolled/slid off a table and continues down, horizontal, or up.

Toss

Object in hand is tossed down, falls UP, tossed up, falls DOWN.

Ramp

Object is placed in center of ramp and released to roll down or up.

Inertia

Stop

Object rolls from one side of screen and stops in the middle, then re-starts on its own, or by a hand.

Reverse

Object rolls/slides from one side of the screen and collides with a barrier, or takes the same trajectory colliding against no bairrier.

Support

Fall

An object is placed (mostly on/slightly on/next to/near) on a cabinet and immediately falls.

Stay

An object is placed (mostly on/slightly on/next to/near) on a cabinet and stays there.

Control

Same

Distinguishable but similar physically-possible human actions on objects, like rotating an object about one axis vs. another

Salience

Physically-possible human actions on objects, some more interesting, like flipping a spoon vs. slowly extending it or erasing a drawing vs. an empty board.

Calibration

A spinning ball moves across the entire screen.

Dataset contents

Here we describe the information that will be available in the final dataset. Some of this info is not available for the pilot dataset, in particular anything having to do with more than one session.

Per child

  • Age at start

  • Demographic info (optional, typically reported): family income, languages spoken at home, parent education level(s), number of parents in the home, number of children’s books in the home, child’s race, number and age of siblings, country + US state if in US, urban/suburban/rural

Per session

  • Child’s age

  • Number of previous sessions completed

  • Time since last session

  • Mood data (Before beginning study, by parent report. Scales 1-7: CHILD: tired-rested, sick-healthy, fussy-happy, calm-active; PARENT: tired-energetic, overwhelmed-ontopofthings, upset-happy. How long since child woke up, how long since child ate, how long until child is due for nap/sleep; what child was doing before this.)

Per trial

  • Time looking L, R (full time sequence of looks left, right, away)

  • Number of fixations (derived from the first one)

  • Proportion looking to L, out of time looking to screen (derived from the first one)

  • Parent behavior: times of talking, pointing, and peeking

  • Infant behavior: times of fussing & rating of fussiness level low or high

  • Trial number

Predictors for fraction time to left

  • Comparison type (e.g. ramp up vs. down), nested within

  • Event type (e.g. ramp), nested within…

  • Concept (gravity, inertia, support)

  • Object (apple, lotion bottle, scissors…)

  • Whether each side is unexpected (i.e., does the event on the left clearly violate a physical principle? Does the event on the right? Sometimes both are unexpected to adults, e.g. when an object near a cabinet and an object next-to a cabinet stay put; sometimes neither is. In some cases this depends on the child’s potential beliefs, see modeling…) & which side is less expected.

Data acquisition and exclusion

Sample size & recruitment procedures

Age range 4-12 months at start of study; continue for up to 61 days; target ‘complete’ dataset is 12 usable sessions. (No major age differences in data quality or salience/same controls seen in piloting.)

Plan to recruit as large a balanced sample as practical given time constraints on both testing and recruiting; aiming for 50 participants with a complete dataset. All recruitment decisions are / have been made without examining dependent variables. This will also be the case if we must terminate data collection early (i.e. for timing/funding constraints)

Data exclusion & disambiguation

All partial datasets (<12 sessions) and any extra data collected will be included in the analysis. Data will only be excluded from analysis if it meets any of the criteria below; we aim to include as much data as possible and use analyses that are robust to missing/‘unbalanced’ data. Data may be excluded at the level of the participant (i.e. all data from that child is excluded), sessions, or individual trial.

Note also that because (a) we may exclude some-but-not-all data from a participant and (b) the number of times baby is taken to have seen the study is relevant, the ‘study number’ (= number of sessions seen) may differ from a simple count of the sessions that are present in the dataset.

Child level

  • Gestational age at birth < 37 weeks, for any analyses using age. Unknown gestational age will be used but prevalence reported. (Followup to check that inclusion of premature infants does not qualitatively affect other results, and/or to display results from premature infants with adjusted/non-adjusted age - exploratory.)

  • Children who participated in the pilot study

  • Children whose parents spontaneously report developmental/medical issues that would likely explain some differences in task: vision or hearing impairment; cognitive or neurological disorders including due to trisomies.

  • Note again: We include data from children with any number of sessions (will probably have many with <12 in addition to “complete” data); analyses described should be able to handle this appropriately.

Session level

  • Sessions where children are outside age range of 4-14 months, except for binned-by-age analyses where we may display data from children outside the age range (without affecting any other values) if we end up having it. Adjusted age will be used for premature infants.

  • Sessions with < 6 trials (& don’t count as a session for session # purposes). Parents are encouraged not to complete sessions within 6 hours of each other. For each session (process later -> earlier), if another session with fewer completed trials happened within six hours, use this one instead.This leads to reasonable outcomes even in the unlikely event someone’s doing the study every 5 hours.

  • Require calibration performance >75% to use session. Calibration scores seem to be mostly due to difficulty coding and might therefore index overall confidence in other judgments; timing differences in webcam stream vs. displayed stimuli will also affect calibration. Pool all looking across the two calibration trials to compute an overall calibration score, so that if kids aren’t looking as much for one of the trials we don’t average in a much noisier measurement. Score is fractional looking time to correct side during the middle of periods when the ball should be static: [0.5, 3.5], [5.5, 8.5], [10.5, 13.5], [15.5, 18.5], [20.5, 23.5].

  • If the participant has <12 usable sessions spread over >60 days, use sessions from the earliest 60-day period (inclusive) with the most usable sessions. If the participant has >=12 usable sessions over >60 days, use sessions from the earliest 60-day period (inclusive) with at least 12 sessions.

  • Where absolute session number (as an index of how many times the child has seen stimuli, etc.) is relevant, assign the first session used in analysis a session number according to the number of ‘experienced sessions’ in the preceding 60 days. Experienced sessions include sessions where the child is out of age range or calibration performance is poor, but not sessions with <6 trials. (For instance, if a child participates at 4 months of age and then 12 times from 10-11 months, the latter set of data is used and the first session at 10 months is considered session 1. If a child participates on days 1, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, then sessions starting at day 30 are used but the first session number is 2.

Trial level

  • Require >= 2s looking to use a trial. Don’t otherwise deal with shorter/longer LTs except in (exploratory) model.

  • Omit periods where the child is out of frame or gaze is otherwise impossible to code. Treat as out of frame any periods where the video is ‘frozen’ for >1s (start treating as out of frame 1s after this period begins) and report prevalence.

  • Exclude trials where child is fussing >50% of the trial. In contrast to omitting periods where child is fussing, this avoids dependence on exactly which frames are considered fussy, at the cost of a threshold effect we expect not to affect many trials. >50% applies to length of video, not otherwise codable data (i.e. we allow fuss coding during outofframe periods).

  • Parent interference: Exclude periods of trials after parent peeks, points while peeking, or speaks in any way that could bias child (“what’s that ball doing?” but not “keep looking sweetie!”) Include periods where the parent’s eyes are not visible and we can’t tell where they’re looking (unless there is reason to believe they are looking) and periods where the parent is looking away but may see stimuli peripherally.

Pilot data, visualizations, and sanity checking

We read in the pilot datafile produced by Kim [TODO: Insert dates of test], but for replicability, need to produce a dataset that definitely doesn’t include PII that can be shared alongside the analysis.

We’ll begin by visualizing the pilot dataset for some basic properties. First, we expect that babies’ total looking time will drop over time.

Next, we’ll plot the critical DV - how much time do babies spend looking at surprising things? Note a complication of the dataset here: we will be modeling the ‘raw’ dependent variable, fracLeft (out of some amount of time staring at the screen, what percentage of that time is spent looking at the left-hand video?) and nd asking whether this proportion is affected by lessExpectedLeft - is whichever video is most surprising (from an adult point of view) located on the left or the right?

Remember that lessExpectedLeft corresponds to a different pairing of video types for every event and concept. Critically, this value is undefined for some event types, in particular the SAME events (TODO: add a link to above.)

For ease of visualization, we’ll be plotting fracLessExpected: percentage of time spent looking at which ever video is most surprising. Here is a box plot of looks to these less expected things by concept.

And the same, organized by age.

Build the basic model

Analyses and Preregistration (Simulated dataset)

Discussion/summary of preregistered hypotheses

Construct ‘dummy’ data with some basic expected characteristics

Create simulated data for 12 sessions! We do this by just duplicating the dataset with increasing (equal) slope toward fracLessExpected = 1 (full attention toward most surprising, from adult perspective), and increasing ages by a few days at a time. For items where lessExpected is undefined, we add a bit of noise but leave alone.

#Key columns
# shortId - participant identifier (uuid)
# proquint - readable ID, in case we want to examine cases
# ageRegistration - child age in months + fractional months
# stimuli - stimulus identifier
# trialnum - trial number
# comparison - specific comparison in physics concept (e.g. "on vs. near")
# event - physics event (ramp, etc)
# concept - physics event *category* (lumps a few events together)
# lessExpectedLeft - location of the less expected version (undefined for items that don't have a less expected version!)
# fracLessExpected - Fractional looking time to those trials (undefined for items that don't have a less expected version)
# totalLT - Total trial time in case we want to recover that!

# Construct simulated data (Note, we can make this more complicated over time)
# For now, it assumes that fracLessExpected values just get higher with sessions, on slopes
# determined semi randomly for each child/concept, and that ages get older on a slighly random schedule

simulated_12session_data <- pilotdata %>%
  filter(!is.na(fracLessExpected))%>%
  group_by(shortId, concept) %>%
  dplyr::summarize(startMean_sim = mean(fracLessExpected), slope_sim = abs(rnorm(1,0.05,0.01)), startAge = mean(ageRegistration)) %>%#Small, usually positive slopes
  uncount(12, .id = 'session') %>%
  left_join(filter(pilotdata, !is.na(fracLessExpected))) %>%
  mutate(sim_fracLessExpected = startMean_sim + (session-1)*slope_sim + rnorm(1,0, 0.01)) %>%
  mutate(sim_fracLessExpected = ifelse(sim_fracLessExpected < 1, sim_fracLessExpected, 1)) %>%
  mutate(sim_age = startAge + (session-1)*abs(rnorm(1,0.25,0.5))) #Average 1 week between sessions, no allow negative values

simulated_12session_data <- pilotdata %>%
  filter(is.na(fracLessExpected))%>%
  group_by(shortId, concept) %>%
  dplyr::summarize(startMean_sim = mean(fracLessExpected), slope_sim = abs(rnorm(1,0.05,0.01)), startAge = mean(ageRegistration)) %>%#Small, usually positive slopes
  uncount(12, .id = 'session') %>%
  left_join(filter(pilotdata, !is.na(fracLessExpected))) %>%
  mutate(sim_fracLessExpected = startMean_sim + (session-1)*slope_sim + rnorm(1,0, 0.01)) %>%
  mutate(sim_fracLessExpected = ifelse(sim_fracLessExpected < 1, sim_fracLessExpected, 1)) %>%
  mutate(sim_age = startAge + (session-1)*abs(rnorm(1,0.25,0.5))) #Average 1 week between sessions, no allow negative values

Initial visualizations - SIMULATED DATA

  • And again, with the simulated data

concept_means_per_child_per_session <- simulated_12session_data %>%
  filter(!is.na(fracLessExpected))%>%
  group_by(shortId, concept, session) %>%
  summarise(fLE = mean(sim_fracLessExpected), age = first(sim_age))

g <- ggplot(concept_means_per_child_per_session, aes(y = fLE, x = concept)) +
  geom_boxplot() +
  #facet_wrap(~session) + 
  #geom_point(alpha = 0.05) +
  geom_jitter(alpha = 0.1) +
  geom_hline(yintercept=0.5, linetype = 'dashed')+
  ggtitle('SIMULATED - grand means per concept')
g
  • Graphing by age, each event type separately. (This looks silly because the data is simulated - age and attention to fLE for all concepts both set to increase stepwise)

concept_means_per_child_per_session <- simulated_12session_data %>%
  group_by(shortId, session, concept) %>%
  summarise(fLE = mean(sim_fracLessExpected), age = first(sim_age))

g <- ggplot(concept_means_per_child_per_session, aes(y = fLE, x = age)) +
  geom_jitter(alpha = 0.1) +
  geom_smooth(method = "lm")+
  geom_hline(yintercept=0.5, linetype = 'dashed')+
  facet_wrap(~concept) + 
  ggtitle('Means by age')
g
  • Graphing within concepts, e.g. ‘stay’

stay_means_per_child_per_comparison <- simulated_12session_data %>%
  filter(event == 'stay') %>%
  group_by(shortId, session, comparison) %>%
  summarise(fLE = mean(sim_fracLessExpected), age = first(sim_age))

g <- ggplot(stay_means_per_child_per_comparison, aes(y = fLE, x = age)) +
  geom_jitter(alpha = 0.1) +
  geom_smooth(method = "lm")+
  geom_hline(yintercept=0.5, linetype = 'dashed')+
  facet_wrap(~comparison) + 
  ggtitle('Stay')
g

Then, build up the models

An effect of trial number on TOTAL looking time (prediction: children will look less - totalLT - over time)

m <- lme(totalLT ~ trialnum, data = simulated_12session_data, random = ~ 1 | shortId) # LME model, grouping by participant
summary(m)

m <- lmer(totalLT ~ trialnum + (1 | shortId), data = simulated_12session_data) # LME model, grouping by participant
summary(m)

The key outcome variable is fracLessExpected (fractional looking time to the less-expected video of a pair) for all models. For now, leave out comparisons where this is not defined (need to handle these cases later)

BUT SEE alternate strategy proposed by Jesse: model fracLeft, and then ask whether the factor of interest (TargetLeft) is affected by the stimulus categories we care about.

  • Create the appropriate nested random effects structure. There are two kinds of random effect we want to model: children and stimuli (children have within-condition comparisons, but stimuli do not!).

– What kind of slope terms are needed?

m <- lmer(sim_fracLessExpected  ~ 1 + (1|shortId) + (1|stimuli), data = simulated_12session_data) # LME model, grouping by participant * stimuli
summary(m)
  • Key modeling question: Model Gravity, Support, and Control in 1 model, or split up?

We are less interested in differences among these than in characterizing the trajectory of each. So, ultimately expect to model separately? But for now, keep them together to write the ‘baseline’ model.

Within each (which I think we WILL want to keep together), there are (differently) nested sub-concepts, and then cross-cutting comparisons that test those concepts. As follows:

Concept > Event > comparison

NA > calibration > NA (need to characterize further)

Control > Salience > boring:interesting

Control > Same > A:B

Gravity > Ramp > down:up

Gravity > Toss > down:up (This IS assumed to be the same as for Ramp)

Support > Stay > “mostly-on:next-to”,“near:slightly-on”,“mostly-on:near”,“mostly-on:slightly-on”, “near:next-to”

Support > Fall > “mostly-on:next-to”,“near:slightly-on”,“mostly-on:near”,“mostly-on:slightly-on”, “near:next-to” (These levels ARE equivalent to those in Stay!)

For now, keep all together. This may become intractable!

  • Expect that attention to fracLessExpected may vary for each event type, which are nested within concept types. E.g. Ramp and Fall events are both within the gravity concept. Ramp and Fall are not random (i.e. we don’t necessarily require ability to generalize to all possible ‘gravity tests’?), but they are related. That is, I think that conceptually the following is wrong (and the glmer package hates it), but not sure how to modify.
m <- lmer(sim_fracLessExpected  ~ event + concept + comparison + (1|shortId) + (1|stimuli), data = simulated_12session_data) # LME model, grouping by participant * stimuli
summary(m)
  • Expect fractions to lessExpected to change as children get older, and, indepedently (???), as they have seen more sessions. Expect that both age and session terms interact with trial number (stuff gets more boring as you go along).

Conceptual point: How do we expect them to change? Linearly? Maybe not. In this kind of study, infants seem to have ‘sweet spots’ with some kind of stimuli, where they initially avoid a novel/complex stimulus, then tune into it. (But not in the other direction.) Quadratic slopes by concept?

m <- lmer(sim_fracLessExpected  ~ event + concept + comparison + session*trialnum + sim_age*trialnum + (1 | shortId) + (1|stimuli), data = simulated_12session_data) 
summary(m)
  • …. Okay, pretend we settled on the base model! What we really want to know is whether kids have ‘interesting’ fracLessExpected values (ie different from 50% in either direction, with some constraints on the developmental trajectory), and if so, if their trajectories differ from one another for different concepts. In particular, we would like to estimate when the following concepts depart from chance, and if those estimates differ from one another. Ideally, we’d be able to say something about whether it’s the case that individual children ‘aquire concepts’ in a predictable order.

Control: Salience vs. Same (expect Same to stay at 50%!, by hypothesis/construction of stim there is no consistent difference!) Gravity vs. Support? Gravity Gravity vs. Same? (‘Same’ constitutes an expected baseline. Should it be a comparison for all other questions?) Gravity: Ramp vs. Toss Support: Across stay/fall Support: Stay vs. Fall (across comparisons, but expectations are opposite) Support: “mostly-on:next-to”,“near:slightly-on”,“mostly-on:near”,“mostly-on:slightly-on”, “near:next-to”

For this one, we have some hypothesis-driven predictions about order.

(THESE ARE HARD TO SPECIFY!)

In space: mostly-on slightly-on next-to near

Easiest: mostly-on:near Harder: Hardest: “near:next-to” “mostly-on:next-to”,“near:slightly-on”,“mostly-on:slightly-on”,

The problem

For the purposes of this preregistration, we assume that babies begin by not looking anywhere in particular, and then begin looking longer at surprising things (potentially at different points for different categories of things). This is a major simplifying assumption and may turn out to be flatly wrong in our dataset. See modeling section for details.

There is an uncomfortable fact that we expect that babies may actually look longer at either the less-surpising or more-surprising event, if they can tell the difference. That is, unequal attention in either direction is interpreted as ‘knowing the concept’, while equal attention (e.g. treating the comparison of ball tossing up/down the same as the comparison of oatmeal-stirring to oatmeal-stirring) is interpreted to mean no evidence for knowing that concept.

FORTUNATELY, this is constrained: a standard model is that we expect babies to initially look toward the more familiar thing (because the novel one is too confusing), and then shift toward looking at the surprising thing (which they can learn from/familiar one is too boring.) Qualitatively, it looks like this (from Hunter & Ames 1988):

The solution (for now)

Despite the above, in the realm of physical events specifically, most studies have shown infants to look longer at the surprising thing (though note that they have used single-item presentation rather than two-screen comparisons as we do here.) This suggests two possible solutions for modeling ‘learning curves’:

  • Model linearly: Advantage
LS0tCnRpdGxlOiAiUHJlZmVyZW50aWFsIFBoeXNpY3MgLSBwaWxvdCBhbmFseXNpcyBhbmQgcHJlcmVnaXN0cmF0aW9uISIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAnMicKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgoKYGBge3IgcHJlbGltaW5hcmllcywgZWNobz1GQUxTRX0KbGlicmFyeShoZXJlKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkodGliYmxlKQojbGlicmFyeSh2aW9wbG90KQojbGlicmFyeShjb3JyZ3JhbSkKbGlicmFyeShIbWlzYykKbGlicmFyeShjYXIpCmxpYnJhcnkobmxtZSkgIyBhbGxvd3MgdXNlIG9mIHdlaWdodHMKbGlicmFyeShsbWU0KSAjIG5ld2VyL21haW50YWluZWQsIGFsbG93cyBsb2dpc3RpYyByZWdyZXNzaW9uCmxpYnJhcnkobHNtZWFucykKbGlicmFyeShNdU1JbikKbGlicmFyeShpZHMpCgoKcGlsb3RkYXRhIDwtIHJlYWQuY3N2KGhlcmUoInJhd19kYXRhIiwicGlsb3RfaW5jbHVkZWRfdHJpYWxzLmNzdiIpLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCiNOT1RFOiBXb24ndCB3b3JrIG9mZiBvZiBNZWxpc3NhJ3MgbGFwdG9wIGZvciBwcml2YWN5LCB1c2UgdGhlIGZvbGxvd2luZyBpbnN0ZWFkCiNwaWxvdGRhdGEgPC0gcmVhZC5jc3YoaGVyZSgicmF3X2RhdGEiLCJzYWx0ZWRfcGlsb3RfaW5jbHVkZWRfdHJpYWxzLmNzdiIpLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCmBgYAoKVGhpcyBkb2N1bWVudCBpcyB0aGUgcHJlcmVnaXN0cmF0aW9uIGZvciB0aGUgUHJlZmVyZW50aWFsIFBoeXNpY3MgcHJvamVjdCBvbiBMb29raXQuIERhdGEgY29sbGVjdGlvbiBpcyBjdXJyZW50bHkgdW5kZXJ3YXksIGJ1dCBzYW1wbGUgc2l6ZSBoYXMgYmVlbiBzZXQgcHJpb3IgdG8gZGF0YSBjb2xsZWN0aW9uIGtpY2tvZmYgKDUwIHBhcnRpY2lwYW50cyByZWFjaGluZyAxMnRoIHNlc3Npb24pLCBhbmQgdGhlIHZhc3QgbWFqb3JpdHkgb2YgdmlkZW9zIGhhdmVuJ3QgZXZlbiBiZWVuIGNvZGVkIGZvciBsb29rcywgbXVjaCBsZXNzIGNyaXRpY2FsIERWcyBjYWxjdWxhdGVkLgoKVGhpcyBkb2N1bWVudCBjb250YWlucyBhICpicmllZiogb3JpZW50YXRpb24gdG8gdGhlIHByb2plY3QsIGxpbmtzIHRvIHJlbGV2YW50IG90aGVyIGRvY3VtZW50YXRpb24sIGFuZCBhIHJlcHJvZHVjaWJsZSBzZXQgb2YgYW5hbHlzZXMgdGhhdCByZWFkcyBpbiBhIHNldCBvZiBwaWxvdCBkYXRhLCBnZW5lcmF0ZXMgYSBzaW11bGF0ZWQgZGF0YXNldCwgYW5kIGF0dGVtcHRzIHRvIHNldCB1cCB0aGUgbW9kZWwgY29tcGFyaXNvbnMgd2UgYWN0dWFsbHkgY2FyZSBhYm91dCEKCiMgSW50cm9kdWN0aW9uCgpUaGUgaWRlYSBpcyB0byB1c2UgZGVuc2Ugc2FtcGxpbmcgb2YgaW5kaXZpZHVhbCBpbmZhbnRzIG9uIExvb2tpdCB0byBjb25kdWN0IGEgZGV0YWlsZWQgYXNzZXNzbWVudCBvZiB1bmRlcnN0YW5kaW5nIG9mIHNldmVyYWwgcGh5c2ljYWwgcHJpbmNpcGxlcy4gSG93IHN0YWJsZSBhcmUgaW5kaXZpZHVhbCBjb21wb25lbnRzIGFjcm9zcyBzZXNzaW9ucyBhbmQgaG93IGluZGVwZW5kZW50PyBXaGF0IGRvZXMgcGFydGlhbCBrbm93bGVkZ2UgbG9vayBsaWtlIGF0IHRoZSBpbmRpdmlkdWFsIGxldmVsPwoKV2UgYXJlIGludGVyZXN0ZWQgaW4gaW5mYW50cycgcHJlZmVyZW50aWFsIGxvb2tpbmcgcmF0aW8gdG8gc2ltcGxlIHZpb2xhdGlvbnMgb2Y6CgoqCUdyYXZpdHk6IENvbXBsZXRlbHkgdW5zdXBwb3J0ZWQgb2JqZWN0cyBzaG91bGQgZmFsbCBkb3duIGltbWVkaWF0ZWx5LCByYXRoZXIgdGhhbiBtb3ZpbmcgdXAsIGNvbnRpbnVpbmcgaW4gdGhlaXIgY3VycmVudCB0cmFqZWN0b3J5LCBvciBtb3ZpbmcgZG93biBhdCBzb21lIGRlbGF5LgoKKglJbmVydGlhOiBPYmplY3RzIHNob3VsZCBjb250aW51ZSByb3VnaGx5IGluIHRoZWlyIGN1cnJlbnQgdHJhamVjdG9yeSB3aGVuIGdyYXZpdHkgaXMgbm90IGEgZmFjdG9yLCByYXRoZXIgdGhhbiBzdG9wcGluZyBhbmQgc3RhcnRpbmcgb3IgdHVybmluZyBhcm91bmQuCgoqCVN1cHBvcnQ6IHdoaWNoIG9mIHRoZSBmb2xsb3dpbmcgc2hvdWxkIGZhbGwgKHZzLiBzdGF5IHB1dCkgYWZ0ZXIgYmVpbmcgcGxhY2VkPwoKICAgICsgQW4gb2JqZWN0IHBsYWNlZCBtb3N0bHkgb24gdGhlIGFuY2hvcgoKICAgICsgQW4gb2JqZWN0IHBsYWNlZCBvbmx5IHNsaWdodGx5IG9uIHRoZSBhbmNob3IKCiAgICArIEFuIG9iamVjdCB0b3VjaGluZyB0aGUgc2lkZSBvciBib3R0b20gb2YgdGhlIGFuY2hvcgoKICAgICsgQW4gb2JqZWN0IG5lYXIgdGhlIGFuY2hvciBidXQgbm90IHRvdWNoaW5nIGl0CiAKIyMgQmlnIHBpY3R1cmUKCldoeSBzdHVkeSBpbmRpdmlkdWFsIGJlaGF2aW9yIGluIG1vcmUgZGV0YWlsLS13aGF0IGRvIHdlIGxvc2UgaW4gc3R1ZHlpbmcgZ3JvdXBzIG9mIGtpZHM/IFdlIGRvbuKAmXQga25vdyB0aGUgZXh0ZW50IHRvIHdoaWNoIGEgc3VjY2VzcyBtZWFucyB0aGF0IGEgc2lnbmlmaWNhbnQgZnJhY3Rpb24gb2Yga2lkcyB0aGlzIGFnZSBjYW4gZG8gdGhpcyB0YXNrIFZTIHRoYXQgYWxsIGtpZHMgb2YgdGhpcyBhZ2UgY2FuIGRvIHRoaXMgdGFzayB0byBhIHNpZ25pZmljYW50IGRlZ3JlZS4gQW5kIGV2ZW4gbG9va2luZyBhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHNjb3JlcyBkb2VzbuKAmXQgY2xlYXIgdGhpcyB1cCwgdW5sZXNzIGl04oCZcyBhbiBpbmNyZWRpYmx5IHN0cm9uZyByZXN1bHQgKGUuZy4gYWxsIGtpZHMgZ2V0IDktMTAgb2YgMTAgcXVlc3Rpb25zIHJpZ2h0LCBvciBubyBraWRzIGdldCBtb3JlIHRoYW4gNiBvdXQgb2YgMTApLiAKVGhpcyBtYXR0ZXJzIGZvcgoKKgl1bmRlcnN0YW5kaW5nIGhvdyBhYmlsaXRpZXMgYXJlIHJlbGF0ZWQgdG8gZWFjaCBvdGhlcjogd2UgY2Fu4oCZdCBnZXQgbmVhcmx5IGFzIG11Y2ggb3V0IG9mIGFnZS1iYXNlZCBwcm9ncmVzc2lvbnMgd2l0aG91dCBrbm93aW5nIGhvdyB0aGUgbm9pc2Ugd29ya3PigJRlc3BlY2lhbGx5IGZvciByZXN1bHRzIG9mIHRoZSBmb3JtIOKAnG4tbW9udGgtb2xkcywgYnV0IG5vdCBtLW1vbnRoLW9sZHMsIGNhbiBkbyBY4oCdCgoqCXVuZGVyc3RhbmRpbmcgd2hhdCBwYXJ0aWFsIGtub3dsZWRnZSAmIG1lY2hhbmlzbXMgb2YgY2hhbmdlIGluIGEgZG9tYWluIGxvb2sgbGlrZTogd2hlbiBraWRzIOKAnGZhaWws4oCdIGlzIHRoYXQgc29tZSBraWRzIG1ha2luZyBhIGNvcnJlY3QgcHJlZGljdGlvbiBhbmQgc29tZSBtYWtpbmcgYW4gaW5jb3JyZWN0IHByZWRpY3Rpb24/IE9yIGFyZSB0aGV5IGFsbCBmYWlsaW5nIHRvIG1ha2UgYW55IHByZWRpY3Rpb24gYW5kL29yIHByZWRpY3RpbmcgYXQgY2hhbmNlPyBXaGVuIGtpZHMgc3VjY2VlZCBidXQgbm90IGF0IGNlaWxpbmcsIGFyZSBzb21lIGdldHRpbmcgb25lIGFzcGVjdCBhbmQgc29tZSBhbm90aGVyPwogCkl0IG1heSBiZSB0aGF0IHNvbWUga2lkcyBkb27igJl0IGV4cHJlc3MgbmVhcmx5LXVuaXZlcnNhbCBrbm93bGVkZ2Ugb24gdGhlIGRlcGVuZGVudCBtZWFzdXJlcyB3ZSBjb2xsZWN0LiBXZSBjYW4gZXZhbHVhdGUgdGhpcyBleHBsYW5hdGlvbiBmb3Igbm9pc2UgYW5kL29yIGluZGl2aWR1YWwgZGlmZmVyZW5jZXMgYnkgc3R1ZHlpbmcgdGhlIG1ldGhvZHMgdGhlbXNlbHZlcywgYW5kIGtpZHPigJkgYmVoYXZpb3Igb24gdGhlbTogZS5nLiwgY2FuIHdlIHByZWRpY3QgdGhlIHR5cGVzIG9mIHByZWZlcmVudGlhbCBsb29raW5nIHJlc3BvbnNlcyB3ZSBnZXQgZnJvbSBraWRzIGJhc2VkIG9uIGNvbnRyb2wgdGFza3M/IEhvdyBzdGFibGUgYXJlIHRob3NlIGNvbnRyb2xzIGFuZCB0YXNrIHBlcmZvcm1hbmNlIGFjcm9zcyBzZXNzaW9ucz8gKEVzcGVjaWFsbHkgaW50ZXJlc3Rpbmcgd291bGQgYmUgZGlmZmVyZW5jZXMgd2l0aGluIGtpZHMgaW4gZXhwcmVzc2lvbjoga2lkcyBtYXkgZ2VudWluZWx5IGV4cHJlc3Mga25vd2xlZGdlIGF0IHNvbWUgdGltZXMsIGJ1dCBub3Qgb3RoZXJzLCBkdWUgdG8gYXR0ZW50aW9uYWwvZW1vdGlvbmFsIHN0YXRlIGNoYW5nZXMuKSAKIApFc3BlY2lhbGx5IGluIGRldmVsb3BtZW50LCB3aGVyZSB3ZeKAmXJlIGludGVyZXN0ZWQgaW4gdGhlIHVuZGVycGlubmluZ3Mgb2YgaHVtYW4gY29nbml0aW9uLCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIOKAnHNvbWUgYmFiaWVzIHVzZSB0aGlzIHR5cGUgb2YgaW5mb3JtYXRpb24gYnV0IG90aGVycyBkbyBzb21ldGhpbmcgZWxzZeKAnSBhbmQg4oCcYWxsIGJhYmllcyBoYXZlIHRoaXMgdHlwZSBvZiBpbmZvcm1hdGlvbiBhdmFpbGFibGUgdG8gdGhlbSwgdW5sZXNzIHNvbWV0aGluZ+KAmXMgd3JvbmfigJ0gbWF0dGVycyBhIGxvdOKAlHRoaXMgaXMgZXhhY3RseSB3aGVyZSB3ZSBjYXJlIGFib3V0IHVuaXZlcnNhbGl0eS4gCgojIyBFeHBlcmltZW50YWwgcGFyYWRpZ20KCkNoaWxkcmVuIGNvbXBsZXRlIDI0IDIwLXNlY29uZCBwcmVmZXJlbnRpYWwgbG9va2luZyB0cmlhbHMgcGVyIHNlc3Npb247IGZhbWlsaWVzIGFyZSBlbmNvdXJhZ2VkIHRvIGNvbXBsZXRlIDE1IHNlc3Npb25zIHdpdGhpbiAyIG1vbnRocy4gUGFyZW50cyBjb21wbGV0ZSBhIHNob3J0IG1vb2Qgc3VydmV5IGFuZCBnbyB0aHJvdWdoIHNvbWUgaW5zdHJ1Y3Rpb25zIGJlZm9yZSB0aGUgcHJlZmVyZW50aWFsIGxvb2tpbmcgcG9ydGlvbi4gVGhleeKAmXJlIGFza2VkIHRvIGhvbGQgdGhlaXIgY2hpbGRyZW4gbG9va2luZyBvdmVyIHRoZWlyIHNob3VsZGVycyBkdXJpbmcgdGhpcyBwb3J0aW9uIHRvIGF2b2lkIHBhcmVudGFsIGJpYXMuIFBhcmVudHMgY2FuIGVuZCB0aGUgc3R1ZHkgYXQgYW55IHBvaW50IGFuZCBza2lwIHRvIHRoZSBwb3N0LXN0dWR5IHN1cnZleS4KIApFYWNoIHRyaWFsIGJlZ2lucyB3aXRoIGFuIG9iamVjdCBpbnRybyAodmlkZW8gb2YgS2ltIHNheWluZyDigJxMb29rLCB0aGlzIGlzIGEg4oCm4oCdKSBhbmQgZGVtb25zdHJhdGluZyB1c2Ugb2YgYW4gb2JqZWN0IOKAkyBlLmcuIGJpdGluZyBpbnRvIGFuIGFwcGxlLCBwdXR0aW5nIG9uIGhhbmQgbG90aW9uLCBkcmF3aW5nIHdpdGggYSBtYXJrZXIsIGVhdGluZyB3aXRoIGEgc3Bvb24pIHRoYXQgbGFzdHMgYWJvdXQgNSBzZWNvbmRzLgoKPHZpZGVvIHdpZHRoPSIzMjAiIGhlaWdodD0iMjQwIiBjb250cm9scz4KICA8c291cmNlIHNyYz0iaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL2xvb2tpdGNvbnRlbnRzL2V4cC1waHlzaWNzLWZpbmFsL2V4YW1wbGVzLzBfaW50cm9zQS5tcDQiIHR5cGU9InZpZGVvL21wNCI+CjwvdmlkZW8+CgpUaGlzIGlzIGludGVuZGVkIGFzIGFuIGF0dGVudGlvbi1nZXR0ZXIgdG8gcmUtb3JpZW50IGNoaWxkcmVuIHRvd2FyZHMgdGhlIGNlbnRlciwgd2hpbGUgaW4gcHJpbmNpcGxlIHJlaW5mb3JjaW5nIHRoYXQgdGhlIG9iamVjdCBpbiBxdWVzdGlvbiBpcyBub3QgYW4gYWdlbnQgYW5kIHNob3VsZCBiZSBleHBlY3RlZCB0byBmb2xsb3cgbm9ybWFsIHBoeXNpY2FsIGxhd3MuIAoKVGhlbiwgdHdvIGV2ZW50cyBpbnZvbHZpbmcgdGhhdCBvYmplY3QgYXJlIHNob3duIHNpbXVsdGFuZW91c2x5LCBvbmUgb24gdGhlIGxlZnQgYW5kIG9uZSBvbiB0aGUgcmlnaHQsIGxvb3BpbmcgZm9yIDI0cyAoZXZlbnQgdmlkZW9zIHJhbmdlIGZyb20gYWJvdXQgMi01cykuIEV2ZW50cyBhbHdheXMgc2hvdyB0aGUgc2FtZSBvYmplY3QsIHNhbWUgY2FtZXJhIGFuZ2xlLCBzYW1lIGJhY2tncm91bmQsIHdpdGggYSBkaWZmZXJlbmNlIG9ubHkgaW4gdGhlIOKAnG91dGNvbWUu4oCdIEV2ZW50IHR5cGVzIGFyZSBzaG93biBpbiB0aGUgdGFibGUgYmVsb3c7IGVhY2ggY29uY2VwdCBpcyBwcmVzZW50ZWQgNC02IHRpbWVzLCB3aXRoIDItMyByZXBldGl0aW9ucyBvZiBlYWNoIGV2ZW50IHR5cGUuIEFsdGhvdWdoIGV2ZW50cyBhcmUgc2hvcnQsIHRoZXkgbG9vcCBjb250aW51b3VzbHkgZm9yIDIwcy4gUmVhbHRpbWUgZXZlbnRzIGFyZSBzaG93biBzbyB0aGF0IOKAnGV4cGVjdGVk4oCdIGV2ZW50cyBhcmUgYXQgbmF0dXJhbCBzcGVlZHMsIGFuZCBub3QgcG90ZW50aWFsbHkgc2VlbiBhcyB2aW9sYXRpbmcgcGh5c2ljYWwgcHJpbmNpcGxlcyBkdWUgdG8gaGFwcGVuaW5nIHRvbyBzbG93bHkuCgo8dmlkZW8gd2lkdGg9IjMyMCIgaGVpZ2h0PSIyNDAiIGNvbnRyb2xzIGxvb3A+CiAgPHNvdXJjZSBzcmM9Imh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9sb29raXRjb250ZW50cy9leHAtcGh5c2ljcy1maW5hbC9zdGltdWxpL3RhYmxlL21wNC9zYnNfdGFibGVfY29udGludWVfZG93bl9sb3Rpb25fYzJfMV9OUi5tcDQiIHR5cGU9InZpZGVvL21wNCI+CjwvdmlkZW8+CgpQYXJlbnRzIGNhbiBwYXVzZSBpbmRpdmlkdWFsIHRyaWFscy4gSWYgdGhleSBwYXVzZSBkdXJpbmcgdGhlIGludHJvLCB0aGV5IGp1c3Qgc3RhcnQgb3ZlciB1cG9uIHJlc3RhcnRpbmcuIElmIHRoZXkgcGF1c2UgZHVyaW5nIHRoZSB0ZXN0ICh1cCB0byBvbmUgdGltZSBwZXIgdHJpYWwpIHRoZXkgcmVzdGFydCBmcm9tIHRoZSBpbnRybywgYnV0IHRoZW4gdGhlIGxlZnQgYW5kIHJpZ2h0IHRlc3QgdmlkZW9zIGFyZSBzd2l0Y2hlZCBmb3IgdGhlIHRlc3QgcGhhc2UuCiAKIyMjIFRyaWFsIGFzc2lnbm1lbnQgJiBvcmRlcmluZwoKKFNlZSBiZWxvdyBmb3IgZGVzY3JpcHRpb25zIG9mIHRoZXNlIHRyaWFsIHR5cGVzLikgVHJpYWxzIGN5Y2xlIHRocm91Z2ggZ3Jhdml0eSwgaW5lcnRpYStjYWxpYnJhdGlvbiwgc3VwcG9ydCwgYW5kIGNvbnRyb2wgKHNhbWUvc2FsaWVuY2UpIHBhaXJpbmdzIGR1cmluZyBhIHNlc3Npb247IHRoZSBvcmRlciBvZiB0aGVzZSBjb25jZXB0cyBpcyBjaG9zZW4gZnJvbSBhIGxpc3QgYW5kIGNoYW5nZWQgKGN5Y2xpbmcgdGhyb3VnaCBhIGxpc3Qgb2Ygb3JkZXJzKSBlYWNoIHNlc3Npb24uIFRoZXJlIGFyZSBzaXggdmlkZW9zIHNob3duIGluIGVhY2ggY2F0ZWdvcnkgaW4gdG90YWwuIAoKV2l0aGluIGVhY2ggY2F0ZWdvcnksIG9iamVjdHMgYXJlIGFzc2lnbmVkIHRvIGNvbXBhcmlzb24gdHlwZXMgKGUuZy4g4oCcYXBwbGXigJ0gYXNzaWduZWQgdG8g4oCcdGFibGUsIGRvd24gdnMuIHVw4oCdKSBieSBjaG9vc2luZyBmcm9tIGEgbGlzdCBvZiBhY2NlcHRhYmxlIG1hcHBpbmdzLCBhZ2FpbiBpbmNyZW1lbnRlZCBwZXIgc2Vzc2lvbi4gKFRoZSBmaXJzdCBzZXNzaW9uIHZhbHVlIHdhcyBzZWxlY3RlZCByYW5kb21seSBmcm9tIHRoZSBmaXJzdCBzaXggb3B0aW9ucyBpbml0aWFsbHkgW2J5IGFjY2lkZW50XSwgYW5kIGlzIG5vdyBzZWxlY3RlZCBmcm9tIGFsbCBwb3NzaWJsZSBtYXBwaW5ncy4pIAoKVGhlcmUgYXJlIHNpeCBwb3NzaWJsZSBjb21wYXJpc29ucyBmb3IgdGhlIHN0YXkgYW5kIGZhbGwgZXZlbnRzOyB0aHJlZSBjb21wYXJpc29ucyBhcmUgYXNzaWduZWQgdG8gc3RheSBhbmQgdGhyZWUgdG8gZmFsbCwgd2l0aCB0aGUgc2VsZWN0aW9uIGFnYWluIGN5Y2xpbmcgdGhyb3VnaCBhIHJhbmRvbSBsaXN0IG9mIHN1Y2ggYXNzaWdubWVudHMgcGVyIHNlc3Npb24uIExlZnQvcmlnaHQgcGxhY2VtZW50LCBob3Jpem9udGFsIGZsaXBwaW5nIG9mIHRoZSBsZWZ0IGFuZCByaWdodCBldmVudHMsIGNhbWVyYSBhbmdsZXMsIGFuZCBiYWNrZ3JvdW5kcyBhcmUgY2hvc2VuIHJhbmRvbWx5IHdpdGggdGhlIGNvbnN0cmFpbnQgdGhhdCBoYWxmIG9mIHRoZSDigJhtb3JlIHByb2JhYmxl4oCZIGV2ZW50cyBhcmUgb24gdGhlIGxlZnQgd2l0aGluIGVhY2ggY2F0ZWdvcnkuIENhbGlicmF0aW9uIHRyaWFscyAoZ3JvdXBlZCB3aXRoIGluZXJ0aWEgdmlkZW9zIGZvciBwdXJwb3NlcyBvZiBhc3NpZ25pbmcgb2JqZWN0IGludHJvcykgYXJlIHBsYWNlZCBhdCB0cmlhbHMgMyBhbmQgNiwgc28gdGhhdCB0aGV5IGFyZSBhbHdheXMgYXZhaWxhYmxlIGZvciBraWRzIHdobyBjb21wbGV0ZWQgZW5vdWdoIHRyaWFscyBmb3IgdGhlIHNlc3Npb24gdG8gYmUgaW5jbHVkZWQgKGFuZCBzbyB0aGF0IGlmIHRoZXJlIGFyZSBkaWZmZXJlbmNlcyBpbiBjb2RpbmcgcXVhbGl0eSBhY3Jvc3MgdHJpYWxzLCB3ZeKAmXJlIG5vdCBleGNsdWRpbmcgb24gdGhlIGJhc2lzIG9mIHdoZW4gY2FsaWJyYXRpb24gaGFwcGVuZWQpLgoKCiMjIEV2ZW50IHR5cGVzCgojIyMgR3Jhdml0eQoKIyMjIyBUYWJsZQoKPHZpZGVvIHdpZHRoPSIzMjAiIGhlaWdodD0iMjQwIiBjb250cm9scyBsb29wPgogIDxzb3VyY2Ugc3JjPSJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vbG9va2l0Y29udGVudHMvZXhwLXBoeXNpY3MtZmluYWwvZXhhbXBsZXMvM190YWJsZS5tcDQiIHR5cGU9InZpZGVvL21wNCI+CjwvdmlkZW8+Ck9iamVjdCBpcyByb2xsZWQvc2xpZCBvZmYgYSB0YWJsZSBhbmQgY29udGludWVzICpkb3duKiwgKmhvcml6b250YWwqLCBvciAqdXAqLgoKCiMjIyMgVG9zcyAKCjx2aWRlbyB3aWR0aD0iMzIwIiBoZWlnaHQ9IjI0MCIgY29udHJvbHMgbG9vcD4KICA8c291cmNlIHNyYz0iaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL2xvb2tpdGNvbnRlbnRzL2V4cC1waHlzaWNzLWZpbmFsL2V4YW1wbGVzLzJfdG9zcy5tcDQiIHR5cGU9InZpZGVvL21wNCI+CjwvdmlkZW8+Ck9iamVjdCBpbiBoYW5kIGlzICp0b3NzZWQgZG93biwgZmFsbHMgVVAqLCAqdG9zc2VkIHVwLCBmYWxscyBET1dOKi4KCiMjIyMgUmFtcAoKPHZpZGVvIHdpZHRoPSIzMjAiIGhlaWdodD0iMjQwIiBjb250cm9scyBsb29wPgogIDxzb3VyY2Ugc3JjPSJodHRwczovL3MzLmFtYXpvbmF3cy5jb20vbG9va2l0Y29udGVudHMvZXhwLXBoeXNpY3MtZmluYWwvZXhhbXBsZXMvMV9yYW1wLm1wNCIgdHlwZT0idmlkZW8vbXA0Ij4KPC92aWRlbz4KCk9iamVjdCBpcyBwbGFjZWQgaW4gY2VudGVyIG9mIHJhbXAgYW5kIHJlbGVhc2VkIHRvIHJvbGwgKmRvd24qIG9yICp1cCouCgojIyMgSW5lcnRpYQoKIyMjIyBTdG9wCgo8dmlkZW8gd2lkdGg9IjMyMCIgaGVpZ2h0PSIyNDAiIGNvbnRyb2xzIGxvb3A+CiAgPHNvdXJjZSBzcmM9Imh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9sb29raXRjb250ZW50cy9leHAtcGh5c2ljcy1maW5hbC9leGFtcGxlcy80X3N0b3AubXA0IiB0eXBlPSJ2aWRlby9tcDQiPgo8L3ZpZGVvPgoKT2JqZWN0IHJvbGxzIGZyb20gb25lIHNpZGUgb2Ygc2NyZWVuIGFuZCBzdG9wcyBpbiB0aGUgbWlkZGxlLCB0aGVuIHJlLXN0YXJ0cyAqb24gaXRzIG93biosIG9yICpieSBhIGhhbmQqLgoKIyMjIyBSZXZlcnNlCgo8dmlkZW8gd2lkdGg9IjMyMCIgaGVpZ2h0PSIyNDAiIGNvbnRyb2xzIGxvb3A+CiAgPHNvdXJjZSBzcmM9Imh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9sb29raXRjb250ZW50cy9leHAtcGh5c2ljcy1maW5hbC9leGFtcGxlcy80X3JldmVyc2UubXA0IiB0eXBlPSJ2aWRlby9tcDQiPgo8L3ZpZGVvPgoKT2JqZWN0IHJvbGxzL3NsaWRlcyBmcm9tIG9uZSBzaWRlIG9mIHRoZSBzY3JlZW4gYW5kIGNvbGxpZGVzIHdpdGggYSAqYmFycmllciosIG9yIHRha2VzIHRoZSBzYW1lIHRyYWplY3RvcnkgY29sbGlkaW5nIGFnYWluc3QgKm5vIGJhaXJyaWVyKi4KCiMjIyBTdXBwb3J0CgojIyMjIEZhbGwKCjx2aWRlbyB3aWR0aD0iMzIwIiBoZWlnaHQ9IjI0MCIgY29udHJvbHMgbG9vcD4KICA8c291cmNlIHNyYz0iaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL2xvb2tpdGNvbnRlbnRzL2V4cC1waHlzaWNzLWZpbmFsL2V4YW1wbGVzLzVfZmFsbC5tcDQiIHR5cGU9InZpZGVvL21wNCI+CjwvdmlkZW8+CgpBbiBvYmplY3QgaXMgcGxhY2VkICgqbW9zdGx5IG9uKi8qc2xpZ2h0bHkgb24qLypuZXh0IHRvKi8qbmVhciopIG9uIGEgY2FiaW5ldCBhbmQgaW1tZWRpYXRlbHkgZmFsbHMuCgojIyMjIFN0YXkKCjx2aWRlbyB3aWR0aD0iMzIwIiBoZWlnaHQ9IjI0MCIgY29udHJvbHMgbG9vcD4KICA8c291cmNlIHNyYz0iaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL2xvb2tpdGNvbnRlbnRzL2V4cC1waHlzaWNzLWZpbmFsL2V4YW1wbGVzLzZfc3RheS5tcDQiIHR5cGU9InZpZGVvL21wNCI+CjwvdmlkZW8+CgpBbiBvYmplY3QgaXMgcGxhY2VkICgqbW9zdGx5IG9uKi8qc2xpZ2h0bHkgb24qLypuZXh0IHRvKi8qbmVhciopIG9uIGEgY2FiaW5ldCBhbmQgc3RheXMgdGhlcmUuCgojIyMgQ29udHJvbAoKIyMjIyBTYW1lCgo8dmlkZW8gd2lkdGg9IjMyMCIgaGVpZ2h0PSIyNDAiIGNvbnRyb2xzIGxvb3A+CiAgPHNvdXJjZSBzcmM9Imh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9sb29raXRjb250ZW50cy9leHAtcGh5c2ljcy1maW5hbC9leGFtcGxlcy83X2NvbnRyb2xfc2FtZS5tcDQiIHR5cGU9InZpZGVvL21wNCI+CjwvdmlkZW8+CgpEaXN0aW5ndWlzaGFibGUgYnV0IHNpbWlsYXIgcGh5c2ljYWxseS1wb3NzaWJsZSBodW1hbiBhY3Rpb25zIG9uIG9iamVjdHMsIGxpa2Ugcm90YXRpbmcgYW4gb2JqZWN0IGFib3V0IG9uZSBheGlzIHZzLiBhbm90aGVyCgojIyMjIFNhbGllbmNlCgo8dmlkZW8gd2lkdGg9IjMyMCIgaGVpZ2h0PSIyNDAiIGNvbnRyb2xzIGxvb3A+CiAgPHNvdXJjZSBzcmM9Imh0dHBzOi8vczMuYW1hem9uYXdzLmNvbS9sb29raXRjb250ZW50cy9leHAtcGh5c2ljcy1maW5hbC9leGFtcGxlcy83X2NvbnRyb2xfc2FsaWVuY2UubXA0IiB0eXBlPSJ2aWRlby9tcDQiPgo8L3ZpZGVvPgoKUGh5c2ljYWxseS1wb3NzaWJsZSBodW1hbiBhY3Rpb25zIG9uIG9iamVjdHMsIHNvbWUgbW9yZSBpbnRlcmVzdGluZywgbGlrZSBmbGlwcGluZyBhIHNwb29uIHZzLiBzbG93bHkgZXh0ZW5kaW5nIGl0IG9yIGVyYXNpbmcgYSBkcmF3aW5nIHZzLiBhbiBlbXB0eSBib2FyZC4KCiMjIyMgQ2FsaWJyYXRpb24KCjx2aWRlbyB3aWR0aD0iMzIwIiBoZWlnaHQ9IjI0MCIgY29udHJvbHMgbG9vcD4KICA8c291cmNlIHNyYz0iaHR0cHM6Ly9zMy5hbWF6b25hd3MuY29tL2xvb2tpdGNvbnRlbnRzL2V4cC1waHlzaWNzLWZpbmFsL3N0aW11bGkvYXR0ZW50aW9uL21wNC9jYWxpYnJhdGlvbl9MUi5tcDQiIHR5cGU9InZpZGVvL21wNCI+CjwvdmlkZW8+CgpBIHNwaW5uaW5nIGJhbGwgbW92ZXMgYWNyb3NzIHRoZSBlbnRpcmUgc2NyZWVuLgoKIyMgRGF0YXNldCBjb250ZW50cwoKSGVyZSB3ZSBkZXNjcmliZSB0aGUgaW5mb3JtYXRpb24gdGhhdCB3aWxsIGJlIGF2YWlsYWJsZSBpbiB0aGUgZmluYWwgZGF0YXNldC4gU29tZSBvZiB0aGlzIGluZm8gaXMgKm5vdCogYXZhaWxhYmxlIGZvciB0aGUgcGlsb3QgZGF0YXNldCwgaW4gcGFydGljdWxhciBhbnl0aGluZyBoYXZpbmcgdG8gZG8gd2l0aCBtb3JlIHRoYW4gb25lIHNlc3Npb24uCgojIyMgUGVyIGNoaWxkCgoqCUFnZSBhdCBzdGFydAoKKglEZW1vZ3JhcGhpYyBpbmZvIChvcHRpb25hbCwgdHlwaWNhbGx5IHJlcG9ydGVkKTogZmFtaWx5IGluY29tZSwgbGFuZ3VhZ2VzIHNwb2tlbiBhdCBob21lLCBwYXJlbnQgZWR1Y2F0aW9uIGxldmVsKHMpLCBudW1iZXIgb2YgcGFyZW50cyBpbiB0aGUgaG9tZSwgbnVtYmVyIG9mIGNoaWxkcmVu4oCZcyBib29rcyBpbiB0aGUgaG9tZSwgY2hpbGTigJlzIHJhY2UsIG51bWJlciBhbmQgYWdlIG9mIHNpYmxpbmdzLCBjb3VudHJ5ICsgVVMgc3RhdGUgaWYgaW4gVVMsIHVyYmFuL3N1YnVyYmFuL3J1cmFsCgojIyMgUGVyIHNlc3Npb24KCiogQ2hpbGTigJlzIGFnZQoKKglOdW1iZXIgb2YgcHJldmlvdXMgc2Vzc2lvbnMgY29tcGxldGVkCgoqIFRpbWUgc2luY2UgbGFzdCBzZXNzaW9uCgoqCU1vb2QgZGF0YSAoQmVmb3JlIGJlZ2lubmluZyBzdHVkeSwgYnkgcGFyZW50IHJlcG9ydC4gU2NhbGVzIDEtNzogQ0hJTEQ6IHRpcmVkLXJlc3RlZCwgc2ljay1oZWFsdGh5LCBmdXNzeS1oYXBweSwgY2FsbS1hY3RpdmU7IFBBUkVOVDogdGlyZWQtZW5lcmdldGljLCBvdmVyd2hlbG1lZC1vbnRvcG9mdGhpbmdzLCB1cHNldC1oYXBweS4gSG93IGxvbmcgc2luY2UgY2hpbGQgd29rZSB1cCwgaG93IGxvbmcgc2luY2UgY2hpbGQgYXRlLCBob3cgbG9uZyB1bnRpbCBjaGlsZCBpcyBkdWUgZm9yIG5hcC9zbGVlcDsgd2hhdCBjaGlsZCB3YXMgZG9pbmcgYmVmb3JlIHRoaXMuKQoKIyMjIFBlciB0cmlhbAoKKglUaW1lIGxvb2tpbmcgTCwgUiAoZnVsbCB0aW1lIHNlcXVlbmNlIG9mIGxvb2tzIGxlZnQsIHJpZ2h0LCBhd2F5KQoKKglOdW1iZXIgb2YgZml4YXRpb25zIChkZXJpdmVkIGZyb20gdGhlIGZpcnN0IG9uZSkKCiogUHJvcG9ydGlvbiBsb29raW5nIHRvIEwsIG91dCBvZiB0aW1lIGxvb2tpbmcgdG8gc2NyZWVuIChkZXJpdmVkIGZyb20gdGhlIGZpcnN0IG9uZSkKCioJUGFyZW50IGJlaGF2aW9yOiB0aW1lcyBvZiB0YWxraW5nLCBwb2ludGluZywgYW5kIHBlZWtpbmcKCioJSW5mYW50IGJlaGF2aW9yOiB0aW1lcyBvZiBmdXNzaW5nICYgcmF0aW5nIG9mIGZ1c3NpbmVzcyBsZXZlbCBsb3cgb3IgaGlnaAoKKglUcmlhbCBudW1iZXIKCiMjIyBQcmVkaWN0b3JzIGZvciBmcmFjdGlvbiB0aW1lIHRvIGxlZnQKCioJQ29tcGFyaXNvbiB0eXBlIChlLmcuIHJhbXAgdXAgdnMuIGRvd24pLCBuZXN0ZWQgd2l0aGluCgoqCUV2ZW50IHR5cGUgKGUuZy4gcmFtcCksIG5lc3RlZCB3aXRoaW4uLi4KCioJQ29uY2VwdCAoZ3Jhdml0eSwgaW5lcnRpYSwgc3VwcG9ydCkKCioJT2JqZWN0IChhcHBsZSwgbG90aW9uIGJvdHRsZSwgc2Npc3NvcnMuLi4pCgoqCVdoZXRoZXIgZWFjaCBzaWRlIGlzIHVuZXhwZWN0ZWQgKGkuZS4sIGRvZXMgdGhlIGV2ZW50IG9uIHRoZSBsZWZ0IGNsZWFybHkgdmlvbGF0ZSBhIHBoeXNpY2FsIHByaW5jaXBsZT8gRG9lcyB0aGUgZXZlbnQgb24gdGhlIHJpZ2h0PyBTb21ldGltZXMgYm90aCBhcmUgdW5leHBlY3RlZCB0byBhZHVsdHMsIGUuZy4gd2hlbiBhbiBvYmplY3QgbmVhciBhIGNhYmluZXQgYW5kIGFuIG9iamVjdCBuZXh0LXRvIGEgY2FiaW5ldCBzdGF5IHB1dDsgc29tZXRpbWVzIG5laXRoZXIgaXMuIEluIHNvbWUgY2FzZXMgdGhpcyBkZXBlbmRzIG9uIHRoZSBjaGlsZOKAmXMgcG90ZW50aWFsIGJlbGllZnMsIHNlZSBtb2RlbGluZ+KApikgJiB3aGljaCBzaWRlIGlzICpsZXNzKiBleHBlY3RlZC4KCiMgRGF0YSBhY3F1aXNpdGlvbiBhbmQgZXhjbHVzaW9uIAoKIyMgU2FtcGxlIHNpemUgJiByZWNydWl0bWVudCBwcm9jZWR1cmVzCkFnZSByYW5nZSA0LTEyIG1vbnRocyBhdCBzdGFydCBvZiBzdHVkeTsgY29udGludWUgZm9yIHVwIHRvIDYxIGRheXM7IHRhcmdldCDigJhjb21wbGV0ZeKAmSBkYXRhc2V0IGlzIDEyIHVzYWJsZSBzZXNzaW9ucy4gKE5vIG1ham9yIGFnZSBkaWZmZXJlbmNlcyBpbiBkYXRhIHF1YWxpdHkgb3Igc2FsaWVuY2Uvc2FtZSBjb250cm9scyBzZWVuIGluIHBpbG90aW5nLikKIApQbGFuIHRvIHJlY3J1aXQgYXMgbGFyZ2UgYSBiYWxhbmNlZCBzYW1wbGUgYXMgcHJhY3RpY2FsIGdpdmVuIHRpbWUgY29uc3RyYWludHMgb24gYm90aCB0ZXN0aW5nIGFuZCByZWNydWl0aW5nOyBhaW1pbmcgZm9yIDUwIHBhcnRpY2lwYW50cyB3aXRoIGEgY29tcGxldGUgZGF0YXNldC4gQWxsIHJlY3J1aXRtZW50IGRlY2lzaW9ucyBhcmUgLyBoYXZlIGJlZW4gbWFkZSB3aXRob3V0IGV4YW1pbmluZyBkZXBlbmRlbnQgdmFyaWFibGVzLiBUaGlzIHdpbGwgYWxzbyBiZSB0aGUgY2FzZSBpZiB3ZSBtdXN0IHRlcm1pbmF0ZSBkYXRhIGNvbGxlY3Rpb24gZWFybHkgKGkuZS4gZm9yIHRpbWluZy9mdW5kaW5nIGNvbnN0cmFpbnRzKQoKIyMgRGF0YSBleGNsdXNpb24gJiBkaXNhbWJpZ3VhdGlvbgogIApBbGwgcGFydGlhbCBkYXRhc2V0cyAoPDEyIHNlc3Npb25zKSBhbmQgYW55IGV4dHJhIGRhdGEgY29sbGVjdGVkIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIGFuYWx5c2lzLiBEYXRhIHdpbGwgb25seSBiZSBleGNsdWRlZCBmcm9tIGFuYWx5c2lzIGlmIGl0IG1lZXRzIGFueSBvZiB0aGUgY3JpdGVyaWEgYmVsb3c7IHdlIGFpbSB0byBpbmNsdWRlIGFzIG11Y2ggZGF0YSBhcyBwb3NzaWJsZSBhbmQgdXNlIGFuYWx5c2VzIHRoYXQgYXJlIHJvYnVzdCB0byBtaXNzaW5nLyd1bmJhbGFuY2VkJyBkYXRhLiBEYXRhIG1heSBiZSBleGNsdWRlZCBhdCB0aGUgbGV2ZWwgb2YgdGhlIHBhcnRpY2lwYW50IChpLmUuIGFsbCBkYXRhIGZyb20gdGhhdCBjaGlsZCBpcyBleGNsdWRlZCksIHNlc3Npb25zLCBvciBpbmRpdmlkdWFsIHRyaWFsLiAKCk5vdGUgYWxzbyB0aGF0IGJlY2F1c2UgKGEpIHdlIG1heSBleGNsdWRlIHNvbWUtYnV0LW5vdC1hbGwgZGF0YSBmcm9tIGEgcGFydGljaXBhbnQgYW5kIChiKSB0aGUgbnVtYmVyIG9mIHRpbWVzIGJhYnkgaXMgdGFrZW4gdG8gaGF2ZSBzZWVuIHRoZSBzdHVkeSBpcyByZWxldmFudCwgdGhlICdzdHVkeSBudW1iZXInICg9IG51bWJlciBvZiBzZXNzaW9ucyBzZWVuKSBtYXkgZGlmZmVyIGZyb20gYSBzaW1wbGUgY291bnQgb2YgdGhlIHNlc3Npb25zIHRoYXQgYXJlIHByZXNlbnQgaW4gdGhlIGRhdGFzZXQuIAoKIyMjIENoaWxkIGxldmVsCgoqIEdlc3RhdGlvbmFsIGFnZSBhdCBiaXJ0aCA8IDM3IHdlZWtzLCBmb3IgYW55IGFuYWx5c2VzIHVzaW5nIGFnZS4gVW5rbm93biBnZXN0YXRpb25hbCBhZ2Ugd2lsbCBiZSB1c2VkIGJ1dCBwcmV2YWxlbmNlIHJlcG9ydGVkLiAoRm9sbG93dXAgdG8gY2hlY2sgdGhhdCBpbmNsdXNpb24gb2YgcHJlbWF0dXJlIGluZmFudHMgZG9lcyBub3QgcXVhbGl0YXRpdmVseSBhZmZlY3Qgb3RoZXIgcmVzdWx0cywgYW5kL29yIHRvIGRpc3BsYXkgcmVzdWx0cyBmcm9tIHByZW1hdHVyZSBpbmZhbnRzIHdpdGggYWRqdXN0ZWQvbm9uLWFkanVzdGVkIGFnZSAtIGV4cGxvcmF0b3J5LikKCiogQ2hpbGRyZW4gd2hvIHBhcnRpY2lwYXRlZCBpbiB0aGUgcGlsb3Qgc3R1ZHkKCiogQ2hpbGRyZW4gd2hvc2UgcGFyZW50cyBzcG9udGFuZW91c2x5IHJlcG9ydCBkZXZlbG9wbWVudGFsL21lZGljYWwgaXNzdWVzIHRoYXQgd291bGQgbGlrZWx5IGV4cGxhaW4gc29tZSBkaWZmZXJlbmNlcyBpbiB0YXNrOiB2aXNpb24gb3IgaGVhcmluZyBpbXBhaXJtZW50OyBjb2duaXRpdmUgb3IgbmV1cm9sb2dpY2FsIGRpc29yZGVycyBpbmNsdWRpbmcgZHVlIHRvIHRyaXNvbWllcy4gCgoqIE5vdGUgYWdhaW46IFdlICppbmNsdWRlKiBkYXRhIGZyb20gY2hpbGRyZW4gd2l0aCBhbnkgbnVtYmVyIG9mIHNlc3Npb25zICh3aWxsIHByb2JhYmx5IGhhdmUgbWFueSB3aXRoIDwxMiBpbiBhZGRpdGlvbiB0byDigJxjb21wbGV0ZeKAnSBkYXRhKTsgYW5hbHlzZXMgZGVzY3JpYmVkIHNob3VsZCBiZSBhYmxlIHRvIGhhbmRsZSB0aGlzIGFwcHJvcHJpYXRlbHkuCgoKIyMjIFNlc3Npb24gbGV2ZWwKCiogU2Vzc2lvbnMgd2hlcmUgY2hpbGRyZW4gYXJlIG91dHNpZGUgYWdlIHJhbmdlIG9mIDQtMTQgbW9udGhzLCBleGNlcHQgZm9yIGJpbm5lZC1ieS1hZ2UgYW5hbHlzZXMgd2hlcmUgd2UgbWF5IGRpc3BsYXkgZGF0YSBmcm9tIGNoaWxkcmVuIG91dHNpZGUgdGhlIGFnZSByYW5nZSAod2l0aG91dCBhZmZlY3RpbmcgYW55IG90aGVyIHZhbHVlcykgaWYgd2UgZW5kIHVwIGhhdmluZyBpdC4gQWRqdXN0ZWQgYWdlIHdpbGwgYmUgdXNlZCBmb3IgcHJlbWF0dXJlIGluZmFudHMuCgoqIFNlc3Npb25zIHdpdGggPCA2IHRyaWFscyAoJiBkb27igJl0IGNvdW50IGFzIGEgc2Vzc2lvbiBmb3Igc2Vzc2lvbiAjIHB1cnBvc2VzKS4gUGFyZW50cyBhcmUgZW5jb3VyYWdlZCBub3QgdG8gY29tcGxldGUgc2Vzc2lvbnMgd2l0aGluIDYgaG91cnMgb2YgZWFjaCBvdGhlci4gRm9yIGVhY2ggc2Vzc2lvbiAocHJvY2VzcyBsYXRlciAtPiBlYXJsaWVyKSwgaWYgYW5vdGhlciBzZXNzaW9uIHdpdGggZmV3ZXIgY29tcGxldGVkIHRyaWFscyBoYXBwZW5lZCB3aXRoaW4gc2l4IGhvdXJzLCB1c2UgdGhpcyBvbmUgaW5zdGVhZC5UaGlzIGxlYWRzIHRvIHJlYXNvbmFibGUgb3V0Y29tZXMgZXZlbiBpbiB0aGUgdW5saWtlbHkgZXZlbnQgc29tZW9uZeKAmXMgZG9pbmcgdGhlIHN0dWR5IGV2ZXJ5IDUgaG91cnMuIAoKKiBSZXF1aXJlIGNhbGlicmF0aW9uIHBlcmZvcm1hbmNlID43NSUgdG8gdXNlIHNlc3Npb24uIENhbGlicmF0aW9uIHNjb3JlcyBzZWVtIHRvIGJlIG1vc3RseSBkdWUgdG8gZGlmZmljdWx0eSBjb2RpbmcgYW5kIG1pZ2h0IHRoZXJlZm9yZSBpbmRleCBvdmVyYWxsIGNvbmZpZGVuY2UgaW4gb3RoZXIganVkZ21lbnRzOyB0aW1pbmcgZGlmZmVyZW5jZXMgaW4gd2ViY2FtIHN0cmVhbSB2cy4gZGlzcGxheWVkIHN0aW11bGkgd2lsbCBhbHNvIGFmZmVjdCBjYWxpYnJhdGlvbi4gUG9vbCBhbGwgbG9va2luZyBhY3Jvc3MgdGhlIHR3byBjYWxpYnJhdGlvbiB0cmlhbHMgdG8gY29tcHV0ZSBhbiBvdmVyYWxsIGNhbGlicmF0aW9uIHNjb3JlLCBzbyB0aGF0IGlmIGtpZHMgYXJlbuKAmXQgbG9va2luZyBhcyBtdWNoIGZvciBvbmUgb2YgdGhlIHRyaWFscyB3ZSBkb27igJl0IGF2ZXJhZ2UgaW4gYSBtdWNoIG5vaXNpZXIgbWVhc3VyZW1lbnQuIFNjb3JlIGlzIGZyYWN0aW9uYWwgbG9va2luZyB0aW1lIHRvIGNvcnJlY3Qgc2lkZSBkdXJpbmcgdGhlIG1pZGRsZSBvZiBwZXJpb2RzIHdoZW4gdGhlIGJhbGwgc2hvdWxkIGJlIHN0YXRpYzogWzAuNSwgMy41XSwgWzUuNSwgOC41XSwgWzEwLjUsIDEzLjVdLCBbMTUuNSwgMTguNV0sIFsyMC41LCAyMy41XS4KCiogSWYgdGhlIHBhcnRpY2lwYW50IGhhcyA8MTIgdXNhYmxlIHNlc3Npb25zIHNwcmVhZCBvdmVyID42MCBkYXlzLCB1c2Ugc2Vzc2lvbnMgZnJvbSB0aGUgZWFybGllc3QgNjAtZGF5IHBlcmlvZCAoaW5jbHVzaXZlKSB3aXRoIHRoZSBtb3N0IHVzYWJsZSBzZXNzaW9ucy4gSWYgdGhlIHBhcnRpY2lwYW50IGhhcyA+PTEyIHVzYWJsZSBzZXNzaW9ucyBvdmVyID42MCBkYXlzLCB1c2Ugc2Vzc2lvbnMgZnJvbSB0aGUgZWFybGllc3QgNjAtZGF5IHBlcmlvZCAoaW5jbHVzaXZlKSB3aXRoIGF0IGxlYXN0IDEyIHNlc3Npb25zLiAKCiogV2hlcmUgYWJzb2x1dGUgc2Vzc2lvbiBudW1iZXIgKGFzIGFuIGluZGV4IG9mIGhvdyBtYW55IHRpbWVzIHRoZSBjaGlsZCBoYXMgc2VlbiBzdGltdWxpLCBldGMuKSBpcyByZWxldmFudCwgYXNzaWduIHRoZSBmaXJzdCBzZXNzaW9uIHVzZWQgaW4gYW5hbHlzaXMgYSBzZXNzaW9uIG51bWJlciBhY2NvcmRpbmcgdG8gdGhlIG51bWJlciBvZiDigJhleHBlcmllbmNlZCBzZXNzaW9uc+KAmSBpbiB0aGUgcHJlY2VkaW5nIDYwIGRheXMuIEV4cGVyaWVuY2VkIHNlc3Npb25zIGluY2x1ZGUgc2Vzc2lvbnMgd2hlcmUgdGhlIGNoaWxkIGlzIG91dCBvZiBhZ2UgcmFuZ2Ugb3IgY2FsaWJyYXRpb24gcGVyZm9ybWFuY2UgaXMgcG9vciwgYnV0IG5vdCBzZXNzaW9ucyB3aXRoIDw2IHRyaWFscy4gKEZvciBpbnN0YW5jZSwgaWYgYSBjaGlsZCBwYXJ0aWNpcGF0ZXMgYXQgNCBtb250aHMgb2YgYWdlIGFuZCB0aGVuIDEyIHRpbWVzIGZyb20gMTAtMTEgbW9udGhzLCB0aGUgbGF0dGVyIHNldCBvZiBkYXRhIGlzIHVzZWQgYW5kIHRoZSBmaXJzdCBzZXNzaW9uIGF0IDEwIG1vbnRocyBpcyBjb25zaWRlcmVkIHNlc3Npb24gMS4gSWYgYSBjaGlsZCBwYXJ0aWNpcGF0ZXMgb24gZGF5cyAxLCAzMCwgMzUsIDQwLCA0NSwgNTAsIDU1LCA2MCwgNjUsIDcwLCA3NSwgODAsIHRoZW4gc2Vzc2lvbnMgc3RhcnRpbmcgYXQgZGF5IDMwIGFyZSB1c2VkIGJ1dCB0aGUgZmlyc3Qgc2Vzc2lvbiBudW1iZXIgaXMgMi4KCgojIyMgVHJpYWwgbGV2ZWwKCiogUmVxdWlyZSA+PSAycyBsb29raW5nIHRvIHVzZSBhIHRyaWFsLiBEb27igJl0IG90aGVyd2lzZSBkZWFsIHdpdGggc2hvcnRlci9sb25nZXIgTFRzIGV4Y2VwdCBpbiAoZXhwbG9yYXRvcnkpIG1vZGVsLgoKKiBPbWl0IHBlcmlvZHMgd2hlcmUgdGhlIGNoaWxkIGlzIG91dCBvZiBmcmFtZSBvciBnYXplIGlzIG90aGVyd2lzZSBpbXBvc3NpYmxlIHRvIGNvZGUuIFRyZWF0IGFzIG91dCBvZiBmcmFtZSBhbnkgcGVyaW9kcyB3aGVyZSB0aGUgdmlkZW8gaXMg4oCYZnJvemVu4oCZIGZvciA+MXMgKHN0YXJ0IHRyZWF0aW5nIGFzIG91dCBvZiBmcmFtZSAxcyBhZnRlciB0aGlzIHBlcmlvZCBiZWdpbnMpIGFuZCByZXBvcnQgcHJldmFsZW5jZS4KCiogRXhjbHVkZSB0cmlhbHMgd2hlcmUgY2hpbGQgaXMgZnVzc2luZyA+NTAlIG9mIHRoZSB0cmlhbC4gSW4gY29udHJhc3QgdG8gb21pdHRpbmcgcGVyaW9kcyB3aGVyZSBjaGlsZCBpcyBmdXNzaW5nLCB0aGlzIGF2b2lkcyBkZXBlbmRlbmNlIG9uIGV4YWN0bHkgd2hpY2ggZnJhbWVzIGFyZSBjb25zaWRlcmVkIGZ1c3N5LCBhdCB0aGUgY29zdCBvZiBhIHRocmVzaG9sZCBlZmZlY3Qgd2UgZXhwZWN0IG5vdCB0byBhZmZlY3QgbWFueSB0cmlhbHMuID41MCUgYXBwbGllcyB0byBsZW5ndGggb2YgdmlkZW8sIG5vdCBvdGhlcndpc2UgY29kYWJsZSBkYXRhIChpLmUuIHdlIGFsbG93IGZ1c3MgY29kaW5nIGR1cmluZyBvdXRvZmZyYW1lIHBlcmlvZHMpLgoKKiBQYXJlbnQgaW50ZXJmZXJlbmNlOiBFeGNsdWRlIHBlcmlvZHMgb2YgdHJpYWxzIGFmdGVyIHBhcmVudCBwZWVrcywgcG9pbnRzIHdoaWxlIHBlZWtpbmcsIG9yIHNwZWFrcyBpbiBhbnkgd2F5IHRoYXQgY291bGQgYmlhcyBjaGlsZCAo4oCcd2hhdOKAmXMgdGhhdCBiYWxsIGRvaW5nP+KAnSBidXQgbm90IOKAnGtlZXAgbG9va2luZyBzd2VldGllIeKAnSkgSW5jbHVkZSBwZXJpb2RzIHdoZXJlIHRoZSBwYXJlbnTigJlzIGV5ZXMgYXJlIG5vdCB2aXNpYmxlIGFuZCB3ZSBjYW7igJl0IHRlbGwgd2hlcmUgdGhleeKAmXJlIGxvb2tpbmcgKHVubGVzcyB0aGVyZSBpcyByZWFzb24gdG8gYmVsaWV2ZSB0aGV5IGFyZSBsb29raW5nKSBhbmQgcGVyaW9kcyB3aGVyZSB0aGUgcGFyZW50IGlzIGxvb2tpbmcgYXdheSBidXQgbWF5IHNlZSBzdGltdWxpIHBlcmlwaGVyYWxseS4KCgojIFBpbG90IGRhdGEsIHZpc3VhbGl6YXRpb25zLCBhbmQgc2FuaXR5IGNoZWNraW5nCgpXZSByZWFkIGluIHRoZSBwaWxvdCBkYXRhZmlsZSBwcm9kdWNlZCBieSBLaW0gW1RPRE86IEluc2VydCBkYXRlcyBvZiB0ZXN0XSwgYnV0IGZvciByZXBsaWNhYmlsaXR5LCBuZWVkIHRvIHByb2R1Y2UgYSBkYXRhc2V0IHRoYXQgZGVmaW5pdGVseSBkb2Vzbid0IGluY2x1ZGUgUElJIHRoYXQgY2FuIGJlIHNoYXJlZCBhbG9uZ3NpZGUgdGhlIGFuYWx5c2lzLiAKCmBgYHtyLCBlY2hvID0gRkFMU0V9CmhlYWQocGlsb3RkYXRhKQoKI0NvbHVtbnMgdGhhdCBtYXkgaW5jbHVkZSBQSUkKIy1CaXJ0aGRheQojLVRlc3QgZGF0ZSArIGFnZQojLU5hbWUvZW1haWwgc3RyaW5ncwoKaGVhZChzZWxlY3QocGlsb3RkYXRhLCBjaGlsZC5wcm9maWxlSWQsIGFnZVJlZ2lzdHJhdGlvbiwgYWdlRXhpdHN1cnZleSkpCgojR29vZCBuZXdzISBPbmx5IHByb2ZpbGVJZCBpcyBhIHBvc3NpYmxlIGRhbmdlcjsgZGF0YXNldCBoYXMgYWdlIGJ1dCBpcyBmdWxseSBkYXRlIGZyZWUKI0FkZCBodW1hbi1mcmllbmRseSBJZHMgaW4gcGxhY2Ugb2YgdGhvc2UKc2V0LnNlZWQoMjU0MzIpCnBpbG90ZGF0YSA8LSBwaWxvdGRhdGEgJT4lCiAgZ3JvdXBfYnkoY2hpbGQucHJvZmlsZUlkKSAlPiUKICBtdXRhdGUoY2hpbGQucHJvcXVpbnQgPSBwcm9xdWludCgpKSU+JQogIHVuZ3JvdXAoKSU+JQogIHNlbGVjdCgtYyhjaGlsZC5wcm9maWxlSWQsWCkpCgp3cml0ZS5jc3YocGlsb3RkYXRhLCBoZXJlKCJyYXdfZGF0YSIsInNhbHRlZF9waWxvdF9pbmNsdWRlZF90cmlhbHMuY3N2IikpCgpgYGAKCldlJ2xsIGJlZ2luIGJ5IHZpc3VhbGl6aW5nIHRoZSBwaWxvdCBkYXRhc2V0IGZvciBzb21lIGJhc2ljIHByb3BlcnRpZXMuIEZpcnN0LCB3ZSBleHBlY3QgdGhhdCBiYWJpZXMnIHRvdGFsIGxvb2tpbmcgdGltZSB3aWxsIGRyb3Agb3ZlciB0aW1lLiAKCmBgYHtyLCBlY2hvID0gRkFMU0V9CkxUX21lYW5zX3Blcl9jaGlsZF9wZXJfdHJpYWwgPC0gcGlsb3RkYXRhICU+JQogIGdyb3VwX2J5KHNob3J0SWQsIHRyaWFsbnVtKSAlPiUKICBzdW1tYXJpc2UoVExUID0gbWVhbih0b3RhbExUKSkKCmcgPC0gZ2dwbG90KExUX21lYW5zX3Blcl9jaGlsZF9wZXJfdHJpYWwsIGFlcyh5ID0gVExULCB4ID0gdHJpYWxudW0pKSArCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjEpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSsKICB5bGFiKCdMb29raW5nIHRpbWUgaW4gc2Vjb25kcycpKwogIHhsYWIoJ1RyaWFsIG51bWJlcicpCgpwcmludChnKQpgYGAKCk5leHQsIHdlJ2xsIHBsb3QgdGhlIGNyaXRpY2FsIERWIC0gaG93IG11Y2ggdGltZSBkbyBiYWJpZXMgc3BlbmQgbG9va2luZyBhdCBzdXJwcmlzaW5nIHRoaW5ncz8gTm90ZSBhIGNvbXBsaWNhdGlvbiBvZiB0aGUgZGF0YXNldCBoZXJlOiB3ZSB3aWxsIGJlICptb2RlbGluZyogdGhlICdyYXcnIGRlcGVuZGVudCB2YXJpYWJsZSwgYGZyYWNMZWZ0YCAob3V0IG9mIHNvbWUgYW1vdW50IG9mIHRpbWUgc3RhcmluZyBhdCB0aGUgc2NyZWVuLCB3aGF0IHBlcmNlbnRhZ2Ugb2YgdGhhdCB0aW1lIGlzIHNwZW50IGxvb2tpbmcgYXQgdGhlIGxlZnQtaGFuZCB2aWRlbz8pIGFuZCBuZCBhc2tpbmcgd2hldGhlciB0aGlzIHByb3BvcnRpb24gaXMgYWZmZWN0ZWQgYnkgYGxlc3NFeHBlY3RlZExlZnRgIC0gaXMgd2hpY2hldmVyIHZpZGVvIGlzIG1vc3Qgc3VycHJpc2luZyAoZnJvbSBhbiBhZHVsdCBwb2ludCBvZiB2aWV3KSBsb2NhdGVkIG9uIHRoZSBsZWZ0IG9yIHRoZSByaWdodD8KClJlbWVtYmVyIHRoYXQgYGxlc3NFeHBlY3RlZExlZnRgIGNvcnJlc3BvbmRzIHRvIGEgZGlmZmVyZW50IHBhaXJpbmcgb2YgdmlkZW8gdHlwZXMgZm9yIGV2ZXJ5IGBldmVudGAgYW5kIGBjb25jZXB0YC4gQ3JpdGljYWxseSwgdGhpcyB2YWx1ZSBpcyB1bmRlZmluZWQgZm9yIHNvbWUgZXZlbnQgdHlwZXMsIGluIHBhcnRpY3VsYXIgdGhlIFNBTUUgZXZlbnRzIChUT0RPOiBhZGQgYSBsaW5rIHRvIGFib3ZlLikKCkZvciBlYXNlIG9mIHZpc3VhbGl6YXRpb24sIHdlJ2xsIGJlIHBsb3R0aW5nIGBmcmFjTGVzc0V4cGVjdGVkYDogcGVyY2VudGFnZSBvZiB0aW1lIHNwZW50IGxvb2tpbmcgYXQgd2hpY2ggZXZlciB2aWRlbyBpcyBtb3N0IHN1cnByaXNpbmcuIEhlcmUgaXMgYSBib3ggcGxvdCBvZiBsb29rcyB0byB0aGVzZSBsZXNzIGV4cGVjdGVkIHRoaW5ncyBieSBjb25jZXB0LiAKCmBgYHtyLCBlY2hvID0gRkFMU0V9Cgpjb25jZXB0X21lYW5zX3Blcl9jaGlsZF9wZXJfc2Vzc2lvbiA8LSBwaWxvdGRhdGEgJT4lCiAgZmlsdGVyKCFpcy5uYShmcmFjTGVzc0V4cGVjdGVkKSklPiUKICBncm91cF9ieShzaG9ydElkLCBjb25jZXB0KSAlPiUKICBzdW1tYXJpc2UoZkxFID0gbWVhbihmcmFjTGVzc0V4cGVjdGVkKSwgYWdlID0gZmlyc3QoYWdlUmVnaXN0cmF0aW9uKSkKCmcgPC0gZ2dwbG90KGNvbmNlcHRfbWVhbnNfcGVyX2NoaWxkX3Blcl9zZXNzaW9uLCBhZXMoeSA9IGZMRSwgeCA9IGNvbmNlcHQpKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKGFscGhhID0gMC4xKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0PTAuNSwgbGluZXR5cGUgPSAnZGFzaGVkJykrCiAgZ2d0aXRsZSgnTWVhbnMgcGVyIGNoaWxkLCBwZXIgY29uY2VwdCcpICsKICB5bGFiKCdGcmFjdGlvbiBsb29raW5nIHRpbWUgdG93YXJkIGxlc3MgZXhwZWN0ZWQgKGZMRSknKSsKICB4bGFiKCdDb25jZXB0JykKcHJpbnQoZykKYGBgCgpBbmQgdGhlIHNhbWUsIG9yZ2FuaXplZCBieSBhZ2UuCmBgYHtyLCBlY2hvID0gRkFMU0V9Cgpjb25jZXB0c19tZWFuc19ieV9hZ2UgPC0gcGlsb3RkYXRhICU+JQogIGZpbHRlcighaXMubmEoZnJhY0xlc3NFeHBlY3RlZCkpJT4lCiAgZ3JvdXBfYnkoc2hvcnRJZCwgY29uY2VwdCkgJT4lCiAgc3VtbWFyaXNlKGZMRSA9IG1lYW4oZnJhY0xlc3NFeHBlY3RlZCksIGFnZSA9IGZpcnN0KGFnZVJlZ2lzdHJhdGlvbikpCgpnIDwtIGdncGxvdChjb25jZXB0c19tZWFuc19ieV9hZ2UsIGFlcyh5ID0gZkxFLCB4ID0gYWdlKSkgKwogIGdlb21faml0dGVyKGFscGhhID0gMC4xKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0PTAuNSwgbGluZXR5cGUgPSAnZGFzaGVkJykrCiAgZmFjZXRfd3JhcCh+Y29uY2VwdCkrCiAgeWxhYignRnJhY3Rpb24gbG9va2luZyB0aW1lIHRvd2FyZCBsZXNzIGV4cGVjdGVkIChmTEUpJykrCiAgeGxhYignQWdlIGluIG1vbnRocycpCnByaW50KGcpCmBgYAoKCgojIEJ1aWxkIHRoZSBiYXNpYyBtb2RlbAoKCiMgQW5hbHlzZXMgYW5kIFByZXJlZ2lzdHJhdGlvbiAoU2ltdWxhdGVkIGRhdGFzZXQpCiMgRGlzY3Vzc2lvbi9zdW1tYXJ5IG9mIHByZXJlZ2lzdGVyZWQgaHlwb3RoZXNlcwoKCgojIENvbnN0cnVjdCAnZHVtbXknIGRhdGEgd2l0aCBzb21lIGJhc2ljIGV4cGVjdGVkIGNoYXJhY3RlcmlzdGljcwpDcmVhdGUgc2ltdWxhdGVkIGRhdGEgZm9yIDEyIHNlc3Npb25zISBXZSBkbyB0aGlzIGJ5IGp1c3QgZHVwbGljYXRpbmcgdGhlIGRhdGFzZXQgd2l0aCBpbmNyZWFzaW5nIChlcXVhbCkgc2xvcGUgdG93YXJkIGZyYWNMZXNzRXhwZWN0ZWQgPSAxIChmdWxsIGF0dGVudGlvbiB0b3dhcmQgbW9zdCBzdXJwcmlzaW5nLCBmcm9tIGFkdWx0IHBlcnNwZWN0aXZlKSwgYW5kIGluY3JlYXNpbmcgYWdlcyBieSBhIGZldyBkYXlzIGF0IGEgdGltZS4gRm9yIGl0ZW1zIHdoZXJlIGxlc3NFeHBlY3RlZCBpcyB1bmRlZmluZWQsIHdlIGFkZCBhIGJpdCBvZiBub2lzZSBidXQgbGVhdmUgYWxvbmUuCgpgYGB7cn0KI0tleSBjb2x1bW5zCiMgc2hvcnRJZCAtIHBhcnRpY2lwYW50IGlkZW50aWZpZXIgKHV1aWQpCiMgcHJvcXVpbnQgLSByZWFkYWJsZSBJRCwgaW4gY2FzZSB3ZSB3YW50IHRvIGV4YW1pbmUgY2FzZXMKIyBhZ2VSZWdpc3RyYXRpb24gLSBjaGlsZCBhZ2UgaW4gbW9udGhzICsgZnJhY3Rpb25hbCBtb250aHMKIyBzdGltdWxpIC0gc3RpbXVsdXMgaWRlbnRpZmllcgojIHRyaWFsbnVtIC0gdHJpYWwgbnVtYmVyCiMgY29tcGFyaXNvbiAtIHNwZWNpZmljIGNvbXBhcmlzb24gaW4gcGh5c2ljcyBjb25jZXB0IChlLmcuICJvbiB2cy4gbmVhciIpCiMgZXZlbnQgLSBwaHlzaWNzIGV2ZW50IChyYW1wLCBldGMpCiMgY29uY2VwdCAtIHBoeXNpY3MgZXZlbnQgKmNhdGVnb3J5KiAobHVtcHMgYSBmZXcgZXZlbnRzIHRvZ2V0aGVyKQojIGxlc3NFeHBlY3RlZExlZnQgLSBsb2NhdGlvbiBvZiB0aGUgbGVzcyBleHBlY3RlZCB2ZXJzaW9uICh1bmRlZmluZWQgZm9yIGl0ZW1zIHRoYXQgZG9uJ3QgaGF2ZSBhIGxlc3MgZXhwZWN0ZWQgdmVyc2lvbiEpCiMgZnJhY0xlc3NFeHBlY3RlZCAtIEZyYWN0aW9uYWwgbG9va2luZyB0aW1lIHRvIHRob3NlIHRyaWFscyAodW5kZWZpbmVkIGZvciBpdGVtcyB0aGF0IGRvbid0IGhhdmUgYSBsZXNzIGV4cGVjdGVkIHZlcnNpb24pCiMgdG90YWxMVCAtIFRvdGFsIHRyaWFsIHRpbWUgaW4gY2FzZSB3ZSB3YW50IHRvIHJlY292ZXIgdGhhdCEKCiMgQ29uc3RydWN0IHNpbXVsYXRlZCBkYXRhIChOb3RlLCB3ZSBjYW4gbWFrZSB0aGlzIG1vcmUgY29tcGxpY2F0ZWQgb3ZlciB0aW1lKQojIEZvciBub3csIGl0IGFzc3VtZXMgdGhhdCBmcmFjTGVzc0V4cGVjdGVkIHZhbHVlcyBqdXN0IGdldCBoaWdoZXIgd2l0aCBzZXNzaW9ucywgb24gc2xvcGVzCiMgZGV0ZXJtaW5lZCBzZW1pIHJhbmRvbWx5IGZvciBlYWNoIGNoaWxkL2NvbmNlcHQsIGFuZCB0aGF0IGFnZXMgZ2V0IG9sZGVyIG9uIGEgc2xpZ2hseSByYW5kb20gc2NoZWR1bGUKCnNpbXVsYXRlZF8xMnNlc3Npb25fZGF0YSA8LSBwaWxvdGRhdGEgJT4lCiAgZmlsdGVyKCFpcy5uYShmcmFjTGVzc0V4cGVjdGVkKSklPiUKICBncm91cF9ieShzaG9ydElkLCBjb25jZXB0KSAlPiUKICBkcGx5cjo6c3VtbWFyaXplKHN0YXJ0TWVhbl9zaW0gPSBtZWFuKGZyYWNMZXNzRXhwZWN0ZWQpLCBzbG9wZV9zaW0gPSBhYnMocm5vcm0oMSwwLjA1LDAuMDEpKSwgc3RhcnRBZ2UgPSBtZWFuKGFnZVJlZ2lzdHJhdGlvbikpICU+JSNTbWFsbCwgdXN1YWxseSBwb3NpdGl2ZSBzbG9wZXMKICB1bmNvdW50KDEyLCAuaWQgPSAnc2Vzc2lvbicpICU+JQogIGxlZnRfam9pbihmaWx0ZXIocGlsb3RkYXRhLCAhaXMubmEoZnJhY0xlc3NFeHBlY3RlZCkpKSAlPiUKICBtdXRhdGUoc2ltX2ZyYWNMZXNzRXhwZWN0ZWQgPSBzdGFydE1lYW5fc2ltICsgKHNlc3Npb24tMSkqc2xvcGVfc2ltICsgcm5vcm0oMSwwLCAwLjAxKSkgJT4lCiAgbXV0YXRlKHNpbV9mcmFjTGVzc0V4cGVjdGVkID0gaWZlbHNlKHNpbV9mcmFjTGVzc0V4cGVjdGVkIDwgMSwgc2ltX2ZyYWNMZXNzRXhwZWN0ZWQsIDEpKSAlPiUKICBtdXRhdGUoc2ltX2FnZSA9IHN0YXJ0QWdlICsgKHNlc3Npb24tMSkqYWJzKHJub3JtKDEsMC4yNSwwLjUpKSkgI0F2ZXJhZ2UgMSB3ZWVrIGJldHdlZW4gc2Vzc2lvbnMsIG5vIGFsbG93IG5lZ2F0aXZlIHZhbHVlcwoKc2ltdWxhdGVkXzEyc2Vzc2lvbl9kYXRhIDwtIHBpbG90ZGF0YSAlPiUKICBmaWx0ZXIoaXMubmEoZnJhY0xlc3NFeHBlY3RlZCkpJT4lCiAgZ3JvdXBfYnkoc2hvcnRJZCwgY29uY2VwdCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShzdGFydE1lYW5fc2ltID0gbWVhbihmcmFjTGVzc0V4cGVjdGVkKSwgc2xvcGVfc2ltID0gYWJzKHJub3JtKDEsMC4wNSwwLjAxKSksIHN0YXJ0QWdlID0gbWVhbihhZ2VSZWdpc3RyYXRpb24pKSAlPiUjU21hbGwsIHVzdWFsbHkgcG9zaXRpdmUgc2xvcGVzCiAgdW5jb3VudCgxMiwgLmlkID0gJ3Nlc3Npb24nKSAlPiUKICBsZWZ0X2pvaW4oZmlsdGVyKHBpbG90ZGF0YSwgIWlzLm5hKGZyYWNMZXNzRXhwZWN0ZWQpKSkgJT4lCiAgbXV0YXRlKHNpbV9mcmFjTGVzc0V4cGVjdGVkID0gc3RhcnRNZWFuX3NpbSArIChzZXNzaW9uLTEpKnNsb3BlX3NpbSArIHJub3JtKDEsMCwgMC4wMSkpICU+JQogIG11dGF0ZShzaW1fZnJhY0xlc3NFeHBlY3RlZCA9IGlmZWxzZShzaW1fZnJhY0xlc3NFeHBlY3RlZCA8IDEsIHNpbV9mcmFjTGVzc0V4cGVjdGVkLCAxKSkgJT4lCiAgbXV0YXRlKHNpbV9hZ2UgPSBzdGFydEFnZSArIChzZXNzaW9uLTEpKmFicyhybm9ybSgxLDAuMjUsMC41KSkpICNBdmVyYWdlIDEgd2VlayBiZXR3ZWVuIHNlc3Npb25zLCBubyBhbGxvdyBuZWdhdGl2ZSB2YWx1ZXMKCmBgYAoKCgoKIyBJbml0aWFsIHZpc3VhbGl6YXRpb25zIC0gU0lNVUxBVEVEIERBVEEKKiBBbmQgYWdhaW4sIHdpdGggdGhlIHNpbXVsYXRlZCBkYXRhCgpgYGB7cn0KCmNvbmNlcHRfbWVhbnNfcGVyX2NoaWxkX3Blcl9zZXNzaW9uIDwtIHNpbXVsYXRlZF8xMnNlc3Npb25fZGF0YSAlPiUKICBmaWx0ZXIoIWlzLm5hKGZyYWNMZXNzRXhwZWN0ZWQpKSU+JQogIGdyb3VwX2J5KHNob3J0SWQsIGNvbmNlcHQsIHNlc3Npb24pICU+JQogIHN1bW1hcmlzZShmTEUgPSBtZWFuKHNpbV9mcmFjTGVzc0V4cGVjdGVkKSwgYWdlID0gZmlyc3Qoc2ltX2FnZSkpCgpnIDwtIGdncGxvdChjb25jZXB0X21lYW5zX3Blcl9jaGlsZF9wZXJfc2Vzc2lvbiwgYWVzKHkgPSBmTEUsIHggPSBjb25jZXB0KSkgKwogIGdlb21fYm94cGxvdCgpICsKICAjZmFjZXRfd3JhcCh+c2Vzc2lvbikgKyAKICAjZ2VvbV9wb2ludChhbHBoYSA9IDAuMDUpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdD0wLjUsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpKwogIGdndGl0bGUoJ1NJTVVMQVRFRCAtIGdyYW5kIG1lYW5zIHBlciBjb25jZXB0JykKZwpgYGAKCgoKKiBHcmFwaGluZyBieSBhZ2UsIGVhY2ggZXZlbnQgdHlwZSBzZXBhcmF0ZWx5LiAoVGhpcyBsb29rcyBzaWxseSBiZWNhdXNlIHRoZSBkYXRhIGlzIHNpbXVsYXRlZCAtIGFnZSBhbmQgYXR0ZW50aW9uIHRvIGZMRSBmb3IgYWxsIGNvbmNlcHRzIGJvdGggc2V0IHRvIGluY3JlYXNlIHN0ZXB3aXNlKQoKYGBge3J9Cgpjb25jZXB0X21lYW5zX3Blcl9jaGlsZF9wZXJfc2Vzc2lvbiA8LSBzaW11bGF0ZWRfMTJzZXNzaW9uX2RhdGEgJT4lCiAgZ3JvdXBfYnkoc2hvcnRJZCwgc2Vzc2lvbiwgY29uY2VwdCkgJT4lCiAgc3VtbWFyaXNlKGZMRSA9IG1lYW4oc2ltX2ZyYWNMZXNzRXhwZWN0ZWQpLCBhZ2UgPSBmaXJzdChzaW1fYWdlKSkKCmcgPC0gZ2dwbG90KGNvbmNlcHRfbWVhbnNfcGVyX2NoaWxkX3Blcl9zZXNzaW9uLCBhZXMoeSA9IGZMRSwgeCA9IGFnZSkpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMSkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdD0wLjUsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpKwogIGZhY2V0X3dyYXAofmNvbmNlcHQpICsgCiAgZ2d0aXRsZSgnTWVhbnMgYnkgYWdlJykKZwpgYGAKCiogR3JhcGhpbmcgd2l0aGluIGNvbmNlcHRzLCBlLmcuICdzdGF5JwoKYGBge3J9CgpzdGF5X21lYW5zX3Blcl9jaGlsZF9wZXJfY29tcGFyaXNvbiA8LSBzaW11bGF0ZWRfMTJzZXNzaW9uX2RhdGEgJT4lCiAgZmlsdGVyKGV2ZW50ID09ICdzdGF5JykgJT4lCiAgZ3JvdXBfYnkoc2hvcnRJZCwgc2Vzc2lvbiwgY29tcGFyaXNvbikgJT4lCiAgc3VtbWFyaXNlKGZMRSA9IG1lYW4oc2ltX2ZyYWNMZXNzRXhwZWN0ZWQpLCBhZ2UgPSBmaXJzdChzaW1fYWdlKSkKCmcgPC0gZ2dwbG90KHN0YXlfbWVhbnNfcGVyX2NoaWxkX3Blcl9jb21wYXJpc29uLCBhZXMoeSA9IGZMRSwgeCA9IGFnZSkpICsKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMSkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdD0wLjUsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpKwogIGZhY2V0X3dyYXAofmNvbXBhcmlzb24pICsgCiAgZ2d0aXRsZSgnU3RheScpCmcKYGBgCgoKIyBUaGVuLCBidWlsZCB1cCB0aGUgbW9kZWxzCiAgCkFuIGVmZmVjdCBvZiB0cmlhbCBudW1iZXIgb24gVE9UQUwgbG9va2luZyB0aW1lIChwcmVkaWN0aW9uOiBjaGlsZHJlbiB3aWxsIGxvb2sgbGVzcyAtIHRvdGFsTFQgLSBvdmVyIHRpbWUpCgpgYGB7cn0KbSA8LSBsbWUodG90YWxMVCB+IHRyaWFsbnVtLCBkYXRhID0gc2ltdWxhdGVkXzEyc2Vzc2lvbl9kYXRhLCByYW5kb20gPSB+IDEgfCBzaG9ydElkKSAjIExNRSBtb2RlbCwgZ3JvdXBpbmcgYnkgcGFydGljaXBhbnQKc3VtbWFyeShtKQoKbSA8LSBsbWVyKHRvdGFsTFQgfiB0cmlhbG51bSArICgxIHwgc2hvcnRJZCksIGRhdGEgPSBzaW11bGF0ZWRfMTJzZXNzaW9uX2RhdGEpICMgTE1FIG1vZGVsLCBncm91cGluZyBieSBwYXJ0aWNpcGFudApzdW1tYXJ5KG0pCmBgYAoKCgpUaGUga2V5IG91dGNvbWUgdmFyaWFibGUgaXMgZnJhY0xlc3NFeHBlY3RlZCAoZnJhY3Rpb25hbCBsb29raW5nIHRpbWUgdG8gdGhlIGxlc3MtZXhwZWN0ZWQgdmlkZW8gb2YgYSBwYWlyKSBmb3IgYWxsIG1vZGVscy4gRm9yIG5vdywgbGVhdmUgb3V0IGNvbXBhcmlzb25zIHdoZXJlIHRoaXMgaXMgbm90IGRlZmluZWQgKG5lZWQgdG8gaGFuZGxlIHRoZXNlIGNhc2VzIGxhdGVyKQoKQlVUIFNFRSBhbHRlcm5hdGUgc3RyYXRlZ3kgcHJvcG9zZWQgYnkgSmVzc2U6IG1vZGVsIGZyYWNMZWZ0LCBhbmQgdGhlbiBhc2sgd2hldGhlciB0aGUgZmFjdG9yIG9mIGludGVyZXN0IChUYXJnZXRMZWZ0KSBpcyBhZmZlY3RlZCBieSB0aGUgc3RpbXVsdXMgY2F0ZWdvcmllcyB3ZSBjYXJlIGFib3V0LiAKCiogQ3JlYXRlIHRoZSBhcHByb3ByaWF0ZSBuZXN0ZWQgcmFuZG9tIGVmZmVjdHMgc3RydWN0dXJlLiBUaGVyZSBhcmUgdHdvIGtpbmRzIG9mIHJhbmRvbSBlZmZlY3Qgd2Ugd2FudCB0byBtb2RlbDogY2hpbGRyZW4gYW5kIHN0aW11bGkgKGNoaWxkcmVuIGhhdmUgd2l0aGluLWNvbmRpdGlvbiBjb21wYXJpc29ucywgYnV0IHN0aW11bGkgZG8gbm90ISkuIAoKLS0gV2hhdCBraW5kIG9mIHNsb3BlIHRlcm1zIGFyZSBuZWVkZWQ/IAoKYGBge3J9Cm0gPC0gbG1lcihzaW1fZnJhY0xlc3NFeHBlY3RlZCAgfiAxICsgKDF8c2hvcnRJZCkgKyAoMXxzdGltdWxpKSwgZGF0YSA9IHNpbXVsYXRlZF8xMnNlc3Npb25fZGF0YSkgIyBMTUUgbW9kZWwsIGdyb3VwaW5nIGJ5IHBhcnRpY2lwYW50ICogc3RpbXVsaQpzdW1tYXJ5KG0pCmBgYAoKCiogS2V5IG1vZGVsaW5nIHF1ZXN0aW9uOiBNb2RlbCBHcmF2aXR5LCBTdXBwb3J0LCBhbmQgQ29udHJvbCBpbiAxIG1vZGVsLCBvciBzcGxpdCB1cD8gCgpXZSBhcmUgbGVzcyBpbnRlcmVzdGVkIGluICpkaWZmZXJlbmNlcyBhbW9uZyB0aGVzZSogdGhhbiBpbiAgKmNoYXJhY3Rlcml6aW5nIHRoZSB0cmFqZWN0b3J5IG9mKiBlYWNoLiBTbywgdWx0aW1hdGVseSBleHBlY3QgdG8gbW9kZWwgc2VwYXJhdGVseT8gQnV0IGZvciBub3csIGtlZXAgdGhlbSB0b2dldGhlciB0byB3cml0ZSB0aGUgJ2Jhc2VsaW5lJyBtb2RlbC4gCgpXaXRoaW4gZWFjaCAod2hpY2ggSSB0aGluayB3ZSBXSUxMIHdhbnQgdG8ga2VlcCB0b2dldGhlciksIHRoZXJlIGFyZSAoZGlmZmVyZW50bHkpIG5lc3RlZCBzdWItY29uY2VwdHMsIGFuZCB0aGVuIGNyb3NzLWN1dHRpbmcgY29tcGFyaXNvbnMgdGhhdCB0ZXN0IHRob3NlIGNvbmNlcHRzLiAgQXMgZm9sbG93czoKCkNvbmNlcHQgPiBFdmVudCA+IGNvbXBhcmlzb24KCk5BID4gY2FsaWJyYXRpb24gPiBOQSAobmVlZCB0byBjaGFyYWN0ZXJpemUgZnVydGhlcikKCkNvbnRyb2wgPiBTYWxpZW5jZSA+IGJvcmluZzppbnRlcmVzdGluZwoKQ29udHJvbCA+IFNhbWUgPiBBOkIKCkdyYXZpdHkgPiBSYW1wID4gZG93bjp1cAoKR3Jhdml0eSA+IFRvc3MgPiBkb3duOnVwIChUaGlzIElTIGFzc3VtZWQgdG8gYmUgdGhlIHNhbWUgYXMgZm9yIFJhbXApCgpTdXBwb3J0ID4gU3RheSA+ICJtb3N0bHktb246bmV4dC10byIsIm5lYXI6c2xpZ2h0bHktb24iLCJtb3N0bHktb246bmVhciIsIm1vc3RseS1vbjpzbGlnaHRseS1vbiIsICJuZWFyOm5leHQtdG8iICAgICAgCgpTdXBwb3J0ID4gRmFsbCA+ICJtb3N0bHktb246bmV4dC10byIsIm5lYXI6c2xpZ2h0bHktb24iLCJtb3N0bHktb246bmVhciIsIm1vc3RseS1vbjpzbGlnaHRseS1vbiIsICJuZWFyOm5leHQtdG8iIChUaGVzZSBsZXZlbHMgQVJFIGVxdWl2YWxlbnQgdG8gdGhvc2UgaW4gU3RheSEpCgpGb3Igbm93LCBrZWVwIGFsbCB0b2dldGhlci4gVGhpcyBtYXkgYmVjb21lIGludHJhY3RhYmxlIQogCiogRXhwZWN0IHRoYXQgYXR0ZW50aW9uIHRvIGZyYWNMZXNzRXhwZWN0ZWQgbWF5IHZhcnkgZm9yIGVhY2ggKmV2ZW50IHR5cGUqLCB3aGljaCBhcmUgbmVzdGVkIHdpdGhpbiAqY29uY2VwdCB0eXBlcyouICBFLmcuIFJhbXAgYW5kIEZhbGwgZXZlbnRzIGFyZSBib3RoIHdpdGhpbiB0aGUgZ3Jhdml0eSAqY29uY2VwdCouICBSYW1wIGFuZCBGYWxsIGFyZSAqbm90IHJhbmRvbSogKGkuZS4gd2UgZG9uJ3QgbmVjZXNzYXJpbHkgcmVxdWlyZSBhYmlsaXR5IHRvIGdlbmVyYWxpemUgdG8gYWxsIHBvc3NpYmxlICdncmF2aXR5IHRlc3RzJz8pLCBidXQgdGhleSAqYXJlIHJlbGF0ZWQqLiAgIFRoYXQgaXMsIEkgdGhpbmsgdGhhdCBjb25jZXB0dWFsbHkgdGhlIGZvbGxvd2luZyBpcyB3cm9uZyAoYW5kIHRoZSBnbG1lciBwYWNrYWdlIGhhdGVzIGl0KSwgYnV0IG5vdCBzdXJlIGhvdyB0byBtb2RpZnkuIAoKYGBge3J9Cm0gPC0gbG1lcihzaW1fZnJhY0xlc3NFeHBlY3RlZCAgfiBldmVudCArIGNvbmNlcHQgKyBjb21wYXJpc29uICsgKDF8c2hvcnRJZCkgKyAoMXxzdGltdWxpKSwgZGF0YSA9IHNpbXVsYXRlZF8xMnNlc3Npb25fZGF0YSkgIyBMTUUgbW9kZWwsIGdyb3VwaW5nIGJ5IHBhcnRpY2lwYW50ICogc3RpbXVsaQpzdW1tYXJ5KG0pCmBgYAoKKiBFeHBlY3QgZnJhY3Rpb25zIHRvIGxlc3NFeHBlY3RlZCB0byBjaGFuZ2UgYXMgY2hpbGRyZW4gZ2V0IG9sZGVyLCBhbmQsIGluZGVwZWRlbnRseSAoPz8/KSwgYXMgdGhleSBoYXZlIHNlZW4gbW9yZSBzZXNzaW9ucy4gRXhwZWN0IHRoYXQgYm90aCBhZ2UgYW5kIHNlc3Npb24gdGVybXMgaW50ZXJhY3Qgd2l0aCB0cmlhbCBudW1iZXIgKHN0dWZmIGdldHMgbW9yZSBib3JpbmcgYXMgeW91IGdvIGFsb25nKS4KCkNvbmNlcHR1YWwgcG9pbnQ6ICpIb3cqIGRvIHdlIGV4cGVjdCB0aGVtIHRvIGNoYW5nZT8gTGluZWFybHk/IE1heWJlIG5vdC4gSW4gdGhpcyBraW5kIG9mIHN0dWR5LCBpbmZhbnRzIHNlZW0gdG8gaGF2ZSAnc3dlZXQgc3BvdHMnIHdpdGggc29tZSBraW5kIG9mIHN0aW11bGksIHdoZXJlIHRoZXkgaW5pdGlhbGx5IGF2b2lkIGEgbm92ZWwvY29tcGxleCBzdGltdWx1cywgdGhlbiB0dW5lIGludG8gaXQuIChCdXQgbm90IGluIHRoZSBvdGhlciBkaXJlY3Rpb24uKSAgUXVhZHJhdGljIHNsb3BlcyBieSBjb25jZXB0PyAKCmBgYHtyfQptIDwtIGxtZXIoc2ltX2ZyYWNMZXNzRXhwZWN0ZWQgIH4gZXZlbnQgKyBjb25jZXB0ICsgY29tcGFyaXNvbiArIHNlc3Npb24qdHJpYWxudW0gKyBzaW1fYWdlKnRyaWFsbnVtICsgKDEgfCBzaG9ydElkKSArICgxfHN0aW11bGkpLCBkYXRhID0gc2ltdWxhdGVkXzEyc2Vzc2lvbl9kYXRhKSAKc3VtbWFyeShtKQpgYGAKCiogLi4uLiBPa2F5LCBwcmV0ZW5kIHdlIHNldHRsZWQgb24gdGhlIGJhc2UgbW9kZWwhIFdoYXQgd2UgcmVhbGx5IHdhbnQgdG8ga25vdyBpcyB3aGV0aGVyIGtpZHMgaGF2ZSAnaW50ZXJlc3RpbmcnIGZyYWNMZXNzRXhwZWN0ZWQgdmFsdWVzIChpZSBkaWZmZXJlbnQgZnJvbSA1MCUgaW4gZWl0aGVyIGRpcmVjdGlvbiwgd2l0aCBzb21lIGNvbnN0cmFpbnRzIG9uIHRoZSBkZXZlbG9wbWVudGFsIHRyYWplY3RvcnkpLCBhbmQgaWYgc28sIGlmIHRoZWlyIHRyYWplY3RvcmllcyBkaWZmZXIgZnJvbSBvbmUgYW5vdGhlciBmb3IgZGlmZmVyZW50IGNvbmNlcHRzLiAgSW4gcGFydGljdWxhciwgd2Ugd291bGQgbGlrZSB0byBlc3RpbWF0ZSAqd2hlbiogdGhlIGZvbGxvd2luZyBjb25jZXB0cyBkZXBhcnQgZnJvbSBjaGFuY2UsIGFuZCAqaWYqIHRob3NlIGVzdGltYXRlcyBkaWZmZXIgZnJvbSBvbmUgYW5vdGhlci4gSWRlYWxseSwgd2UnZCBiZSBhYmxlIHRvIHNheSBzb21ldGhpbmcgYWJvdXQgd2hldGhlciBpdCdzIHRoZSBjYXNlIHRoYXQgaW5kaXZpZHVhbCBjaGlsZHJlbiAnYXF1aXJlIGNvbmNlcHRzJyBpbiBhIHByZWRpY3RhYmxlIG9yZGVyLiAKCkNvbnRyb2w6IFNhbGllbmNlIHZzLiBTYW1lIChleHBlY3QgU2FtZSB0byBzdGF5IGF0IDUwJSEsIGJ5IGh5cG90aGVzaXMvY29uc3RydWN0aW9uIG9mIHN0aW0gdGhlcmUgaXMgbm8gY29uc2lzdGVudCBkaWZmZXJlbmNlISkKR3Jhdml0eSB2cy4gU3VwcG9ydD8KR3Jhdml0eQpHcmF2aXR5IHZzLiBTYW1lPyAoJ1NhbWUnIGNvbnN0aXR1dGVzIGFuIGV4cGVjdGVkIGJhc2VsaW5lLiBTaG91bGQgaXQgYmUgYSBjb21wYXJpc29uIGZvciBhbGwgb3RoZXIgcXVlc3Rpb25zPykKR3Jhdml0eTogUmFtcCB2cy4gVG9zcwpTdXBwb3J0OiBBY3Jvc3Mgc3RheS9mYWxsClN1cHBvcnQ6IFN0YXkgdnMuIEZhbGwgKGFjcm9zcyBjb21wYXJpc29ucywgYnV0IGV4cGVjdGF0aW9ucyBhcmUgb3Bwb3NpdGUpClN1cHBvcnQ6ICJtb3N0bHktb246bmV4dC10byIsIm5lYXI6c2xpZ2h0bHktb24iLCJtb3N0bHktb246bmVhciIsIm1vc3RseS1vbjpzbGlnaHRseS1vbiIsICJuZWFyOm5leHQtdG8iCgpGb3IgdGhpcyBvbmUsIHdlIGhhdmUgc29tZSBoeXBvdGhlc2lzLWRyaXZlbiBwcmVkaWN0aW9ucyBhYm91dCBvcmRlci4KCihUSEVTRSBBUkUgSEFSRCBUTyBTUEVDSUZZISkKCkluIHNwYWNlOiBtb3N0bHktb24gc2xpZ2h0bHktb24gbmV4dC10byBuZWFyCgpFYXNpZXN0OiBtb3N0bHktb246bmVhcgpIYXJkZXI6IApIYXJkZXN0OiAibmVhcjpuZXh0LXRvIgoibW9zdGx5LW9uOm5leHQtdG8iLCJuZWFyOnNsaWdodGx5LW9uIiwibW9zdGx5LW9uOnNsaWdodGx5LW9uIiwgCgoKCiMjIFRoZSBwcm9ibGVtCgpGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgcHJlcmVnaXN0cmF0aW9uLCB3ZSBhc3N1bWUgdGhhdCBiYWJpZXMgYmVnaW4gYnkgbm90IGxvb2tpbmcgYW55d2hlcmUgaW4gcGFydGljdWxhciwgYW5kIHRoZW4gYmVnaW4gbG9va2luZyBsb25nZXIgYXQgc3VycHJpc2luZyB0aGluZ3MgKHBvdGVudGlhbGx5IGF0IGRpZmZlcmVudCBwb2ludHMgZm9yIGRpZmZlcmVudCBjYXRlZ29yaWVzIG9mIHRoaW5ncykuICpUaGlzIGlzIGEgbWFqb3Igc2ltcGxpZnlpbmcgYXNzdW1wdGlvbiogYW5kIG1heSB0dXJuIG91dCB0byBiZSBmbGF0bHkgd3JvbmcgaW4gb3VyIGRhdGFzZXQuIFNlZSBtb2RlbGluZyBzZWN0aW9uIGZvciBkZXRhaWxzLiAKClRoZXJlIGlzIGFuIHVuY29tZm9ydGFibGUgZmFjdCB0aGF0IHdlIGV4cGVjdCB0aGF0IGJhYmllcyBtYXkgYWN0dWFsbHkgbG9vayBsb25nZXIgYXQgKmVpdGhlciogdGhlIGxlc3Mtc3VycGlzaW5nIG9yIG1vcmUtc3VycHJpc2luZyBldmVudCwgaWYgdGhleSBjYW4gdGVsbCB0aGUgZGlmZmVyZW5jZS4gVGhhdCBpcywgdW5lcXVhbCBhdHRlbnRpb24gaW4gZWl0aGVyIGRpcmVjdGlvbiBpcyBpbnRlcnByZXRlZCBhcyAna25vd2luZyB0aGUgY29uY2VwdCcsIHdoaWxlIGVxdWFsIGF0dGVudGlvbiAoZS5nLiB0cmVhdGluZyB0aGUgY29tcGFyaXNvbiBvZiBiYWxsIHRvc3NpbmcgdXAvZG93biB0aGUgc2FtZSBhcyB0aGUgY29tcGFyaXNvbiBvZiBvYXRtZWFsLXN0aXJyaW5nIHRvIG9hdG1lYWwtc3RpcnJpbmcpIGlzIGludGVycHJldGVkIHRvIG1lYW4gbm8gZXZpZGVuY2UgZm9yIGtub3dpbmcgdGhhdCBjb25jZXB0LiAKCkZPUlRVTkFURUxZLCB0aGlzIGlzIGNvbnN0cmFpbmVkOiBhIHN0YW5kYXJkIG1vZGVsIGlzIHRoYXQgd2UgZXhwZWN0IGJhYmllcyB0byBpbml0aWFsbHkgbG9vayB0b3dhcmQgdGhlIG1vcmUgZmFtaWxpYXIgdGhpbmcgKGJlY2F1c2UgdGhlIG5vdmVsIG9uZSBpcyB0b28gY29uZnVzaW5nKSwgYW5kIHRoZW4gc2hpZnQgdG93YXJkIGxvb2tpbmcgYXQgdGhlIHN1cnByaXNpbmcgdGhpbmcgKHdoaWNoIHRoZXkgY2FuIGxlYXJuIGZyb20vZmFtaWxpYXIgb25lIGlzIHRvbyBib3JpbmcuKSAgUXVhbGl0YXRpdmVseSwgaXQgbG9va3MgbGlrZSB0aGlzIChmcm9tIEh1bnRlciAmIEFtZXMgMTk4OCk6CgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmNhcD0iSHVudGVyICYgQW1lcyAoMTk4OCkgY3VydmUiLCBvdXQud2lkdGggPSAnMTAwJSd9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmUoImFuYWx5c2lzL2ZpZ3MvaHVudGVyLWFtZXMucG5nIikpCmBgYAoKIyMgVGhlIHNvbHV0aW9uIChmb3Igbm93KQoKRGVzcGl0ZSB0aGUgYWJvdmUsIGluIHRoZSByZWFsbSBvZiBwaHlzaWNhbCBldmVudHMgc3BlY2lmaWNhbGx5LCBtb3N0IHN0dWRpZXMgaGF2ZSBzaG93biBpbmZhbnRzIHRvIGxvb2sgbG9uZ2VyIGF0IHRoZSBzdXJwcmlzaW5nIHRoaW5nICh0aG91Z2ggbm90ZSB0aGF0IHRoZXkgaGF2ZSB1c2VkIHNpbmdsZS1pdGVtIHByZXNlbnRhdGlvbiByYXRoZXIgdGhhbiB0d28tc2NyZWVuIGNvbXBhcmlzb25zIGFzIHdlIGRvIGhlcmUuKSBUaGlzIHN1Z2dlc3RzIHR3byBwb3NzaWJsZSBzb2x1dGlvbnMgZm9yIG1vZGVsaW5nICdsZWFybmluZyBjdXJ2ZXMnOgoKLSBNb2RlbCBsaW5lYXJseTogQWR2YW50YWdlIAoK